前言
许久没写博客了,7月初去广州一家公司面试了实习生的岗位,是一家小型的创业公司,目前主要做外包业务。作为人生中第一次面试,感觉还是挺宝贵的。刚到广州的时候下着雨,一个人为了一件事走在一个陌生的城市,是一种熟悉又陌生的感觉。广州这座城市给我的感觉:安静,一切都井然有序,繁华,但你关注的绝对不是他的繁华,然后就是四通八达的地铁,我几天的出行全都是地铁,深切的感受到广州交通的发达。
第二天上午到的公司面试,不知道为什么我没有太紧张,由于是初创公司,面试官就是ceo,直接三轮面完我,andorid和java准备了蛮多的不过他都没有问,而是针对一个问题深挖,叫我给出解决方案,我感觉目的是在考我思维的全面性和解决问题的能力,然后就是谈我做过的项目。后来聊了薪资,在聊了我平时的学习方式等等,最后让我等通知。因为在拉勾上投的,他们招的是正式工,我只能作为实习生的身份可能提的薪资比较高了,我觉得初创企业很少愿意花成本去培养一个学生吧,感觉那个薪资我要是老板也宁愿找一个有工作经验的。
回来以后我觉的,是应该改变一下了,我觉得自己数据结构算法等基础不太扎实,又觉得android那块想继续深入学,在掘金上问了大牛,大牛给我的建议,我觉得确实也是很中肯,android什么的可以以后在继续深入学习,但是数据结构算法等这种,是最基础最核心的东西,短时间可能感觉不到,但是对我们影响还是蛮深远的。
所以这几天在练车的间隙,就在抽时间学习数据结构和算法,实现了基本的顺序表和链表(c++)。我觉得写博客真的蛮好的,比起那些杂乱的代码,将来生疏了的内容在自己博客里查找一些就好了。
顺序表
其实数据结构这种东西,语言什么的影响不大,一通百通,之前有用java实现过,这次用c++自己先保证不参考书的情况下,也能实现,顺便回顾下c++。
顺序表在java和c++中有点不一样,其实也没有不一样吧,只是书上实现方式是直接一个固定大小数组,java源码中是初始一个固定大小数组,当增加到一定程度会换数组,比如每增加5个换一个新数组存储,这些都大同小异,主要是实现数据结构的构造,释放,曾删查改等基本操作。好了,话不多说,上代码
先是头文件:
//
// Created by panhao on 17-7-12.
//
#ifndef DATABASE_SEQLIST_H
#define DATABASE_SEQLIST_H
#include <iostream>
const int MaxSize = 100;
template<class Data>
class SeqList {
public:
SeqList() {}
SeqList(Data a[], int n);
~SeqList() {}
int Length() { return this->length; }
Data get(int index);//根据下标查找元素
int Locate(Data data);//按照值来查找
void add(Data data);
void insert(int index, Data data);
Data remove(int index);//根据下标删除元素
void printList();
private:
Data datas[MaxSize];
int length;
};
#endif //DATABASE_SEQLIST_H
这边是声明数组最大为100,然后声明了一个模板类,我更喜欢称为泛型~,然后就是一系列曾删查改等方法。private域存储了作为全局变量的数组和数组的大小。
接下来看具体实现:
//
// Created by panhao on 17-7-12.
//
#include <iostream>
#include "SeqList.h"
using namespace std;
/**
* 有参的构造函数
* @tparam Data
* @param a
* @param n
*/
template<class Data>
SeqList<Data>::SeqList(Data a[], int n) {
if (n > MaxSize)
throw "参数非法";
for (int i = 0; i < n; i++) {
datas[i] = a[i];
}
length = n;
}
/**
* 顺序表的按位查找
* @tparam Data
* @param index
* @return
*/
template<class Data>
Data SeqList<Data>::get(int index) {
if (index > length - 1) {
throw "位置非法";
}
return datas[index];
}
template<class Data>
int SeqList<Data>::Locate(Data data) {
for (int i = 0; i < length; i++) {
if (datas[i] == data) {
return i;
}
}
return -1;
}
template<class Data>
void SeqList<Data>::add(Data data) {
if (length > MaxSize) {
throw "链表超长度";
}
datas[length] = data;
length++;
}
template<class Data>
void SeqList<Data>::insert(int index, Data data) {
if (index > MaxSize) {
throw "溢出";
}
if (index > length - 1 || index < 0) {
throw "位置非法";
}
for (int i = length; i > index; i--) {
datas[i] = datas[i - 1];
}
datas[index] = data;
length++;
}
template<class Data>
Data SeqList<Data>::remove(int index) {
if (index > MaxSize) {
throw "上溢";
}
if (index < 0 || index > length - 1) {
throw "位置非法";
}
//先获得index位置上的值
Data mData = datas[index];
for (int i = index; i < length - 1; i++) {
datas[i] = datas[i + 1];
}
length--;
return mData;
}
template<class Data>
void SeqList<Data>::printList() {
for (int i = 0; i < length; i++) {
cout << datas[i] << endl;
}
}
int main() {
int arr[] = {20, 19, 30, 3, 4, 6, 3, 68};
SeqList<int> seqList = SeqList<int>(arr, 8);
seqList.insert(2, 100);
seqList.remove(2);
int position = seqList.Locate(68);
cout << "position==" << position << endl;
seqList.printList();
int len = seqList.Length();
cout << "len==" << len << endl;
return 0;
}
单独测试的方法我就不一一打印截图,这样太麻烦了,我都有测试过应该是没什么问题的。基本大家的数据结构课程也都会要求写这样的代码。
链表
链表在java和c++中最大的不同就是引用和指针的不同了,不过其实java内部的引用也是通过指针引用,只是被封装了而已。
头文件:
//
// Created by panhao on 17-7-13.
//
#ifndef DATABASE_LINKLIST_H
#define DATABASE_LINKLIST_H
#include <iostream>
using namespace std;
template<class Data>
struct Node {
Data data;
Node<Data> *next;
};
template<class Data>
class LinkList {
public:
LinkList();
LinkList(Data arr[], int n);
LinkList(Node<Data> *first);
~LinkList();
int length();
Data get(int index);
void insert(Data data, int index);
Data remove(int index);
void printList();
private:
Node<Data> *first;//头指针
};
#endif //DATABASE_LINKLIST_H
头文件声明了一个Node的结构体,里面存储了对应的数据类型和下一个节点的指针,指向下一个节点的内存地址。
链表的存储了一个头指针,通过头指针来确认不同节点的位置从而作出不同的操作。
//
// Created by panhao on 17-7-13.
//
#include "LinkList.h"
#include <iostream>
using namespace std;
template<class Data>
LinkList<Data>::LinkList() {
first = new Node<Data>;
first->next = NULL;
}
template<class Data>
LinkList<Data>::LinkList(Data arr[], int n) {
//尾插法,首先确保first是不可变的
first = new Node<Data>;
Node<Data> *tmp = first;//头指针引用
for (int i = 0; i < n; i++) {
//创建一个新的节点并分配内存
Node<Data> *node = new Node<Data>();
node->data = arr[i];
tmp->next = node;
tmp = node;
}
//单链表建立完毕
tmp->next = NULL;
}
/**
* 析构函数~
* @tparam Data
*/
template<class Data>
LinkList<Data>::~LinkList() {
while (first != NULL) {
Node<Data> *q = first;
first = first->next;//first指向被释放的下一个节点
delete q;
}
cout << "链表被finish掉了" << endl;
}
template<class Data>
int LinkList<Data>::length() {
int count = 0;
Node<Data> *p = first;
while (p->next != NULL) {
count++;
p = p->next;
}
return count;
}
template<class Data>
Data LinkList<Data>::get(int index) {
//通过指定的下标获取数据。
if (index > length() || index < 0) {
throw '溢出';
}
Node<Data> *p = first;
int count = 0;
while (count <= index) {
p = p->next;
count++;
}
if (p == NULL) {
throw '位置';
}
return p->data;
}
template<class Data>
void LinkList<Data>::insert(Data data, int index) {
if (index < 0 || index > length()) {
throw '溢出';
}
Node<Data> *p = first;
int count = 0;
while (p != NULL && count < index) {
p = p->next;
count++;
}
if (p == NULL) {
throw '位置';
}
Node<Data> *node = new Node<Data>();
node->data = data;
node->next = p->next;
p->next = node;
}
template<class Data>
Data LinkList<Data>::remove(int index) {
if (index < 0 || index > length()) {
throw '溢出';
}
Node<Data> *p = first;
int count = 0;
while (p != NULL && count < index) {
p = p->next;
count++;
}
if (p == NULL) {
throw '位置';
}
Node<Data> *q = p->next;
Data data = q->data;
p->next = q->next;
delete q;
return data;
}
template<class Data>
void LinkList<Data>::printList() {
Node<Data> *p = first->next;
while (p != NULL) {
cout << p->data << " ";
p = p->next;
}
}
int main() {
int arr[] = {20, 19, 30, 3, 4, 6, 3, 68};
LinkList<int> list(arr, 8);
list.printList();
list.insert(100, 3);
cout << endl;
list.printList();
list.remove(8);
cout << endl;
list.printList();
return 0;
}
这边给个截图吧,因为是新鲜的。
结语
时间有限,明早还要练车,今天就先到这里了,后续会继续学习数据结构算法这些内容,也会顺便学习android更新android的知识。