线性表(c++描述)
最近学了c++,把数据结构用c++再写一遍,加深一下对c++语法的理解
学习c++本来是想利用他的库,节省一下写算法的时间,c语言这种面向过程语言对每个数据结构都要再写一遍,或者因为数据类型,再修改一遍,复用性有比较大的局限性。写了一点线性表的算法后,发现c++的多态性确实很好用,模板类可以很轻松的应用于多种数据类型,但是,对于简单的题目来说,代码有些繁琐,特别是对抽象类的继承,顺序表需要继承这个纯虚函数,但链表不需要,有时候就有点头疼。
另外,吐槽下清华大学出版社的数据结构(c++),错误也太多了。。。
线性表抽象类
template <class T> class LinearList {
//线性表抽象类
public: //抽象类里面不能放构造函数除非函数名相同
virtual int Size() const = 0;
virtual int Lenth() const = 0;
virtual int Search(T &x) const = 0; //在表中搜索x;
virtual int Locate(int i) const = 0; //定位i;
virtual T getdata(int i) const = 0; //获得第i个值,通过x返回
virtual void setdata(int i, T &x) = 0; //修改第i个位置值为x
virtual bool Insert(int i, T &x) = 0; //在i之后插入x
virtual bool Remove(int i, T &x) = 0; //删除i的值,通过x返回
virtual bool Isempty() = 0; // list是否为空
virtual bool Isfull() = 0; //表满
// virtual void Sort() = 0; //表排序
virtual void input() = 0; //表输入
virtual void output() = 0; //表输出
// virtual LinearList<T> operator=(LinearList<T> &L) = 0; //表复制
};
顺序表
template <class T> class SeqList : public LinearList<T> {
//
protected:
T *data;
int maxsize; //表容量
int last; //表元素数
void reSize(int newsize);
public:
SeqList(int m = Maxsize); //构造函数规定表容量,默认值为Maxsize
SeqList(SeqList<T> &L); //复制构造函数
~SeqList() {
delete[] data; } //析构函数
int Size() const {
//最大元素数
return maxsize;
}
int Lenth() const {
//表长
return last + 1;
}
int Search(T &x) const; //在表中搜索x;
int Locate(int i) const; //定位i;
T getdata(int i) const {
//获得第i个值
if (i > 0 && i <= last + 1)
return data[i - 1];
else {
cout << "不在范围内" << endl;
return 0;
}
}
void setdata(int i, T &x) {
//修改第i个位置值为x
if (i > 0 && i <= last + 1)
data[i - 1] = x;
}
bool Insert(int i, T &x); //在第i个元素之后的位置插入x
bool Remove(int i, T &x); //删除i的值,通过x返回
bool Isempty() {
if (last == -1)
return true;
else
return false;
} // list是否为空
bool Isfull() {
return (last + 1 == maxsize) ? true : false; } //表满
void input(); //表输入
void output(); //表输出
// SeqList<T> operator=(SeqList<T> &L) ; //表复制 感觉没必要
};
template <class T> void SeqList<T>::reSize(int newsize) {
//重新规定数组大小
if (newsize <= 0) {
cerr << "无效的大小" << endl;
exit(1);
}
if (newsize != maxsize) {
T *newdata = new T[newsize];
if (newdata == NULL) {
cerr << "存储信息分配错误" << endl;
exit(1); //退出整个进程
}
int n = last + 1;
T *temp1 = data;
T *temp2 = newdata;
while (n--)
*temp2++ = *temp1++; //复制数值到新建数组中
delete[] data; //删除旧值
data = newdata;
maxsize = newsize;
}
}
template <class T> SeqList<T>::SeqList(int m) {
if (m > 0) {
maxsize = m;
last = -1;
data = new T[maxsize];
if (data == NULL) {
cerr << "存储信息分配错误" << endl;
exit(1); //退出整个进程
}
}
}
template <class T> SeqList<T>::SeqList(SeqList<T> &L) {
maxsize = L.Size();
last = L.Lenth() - 1;
data = new T[maxsize];
if (data == NULL) {
cerr << "存储信息分配错误" << endl;
exit(1); //退出整个进程
}
for (int i = 0; i <= last; i++)
data[i] = L.getdata(i + 1); // getdata获得的是第i个数即data[i-1]
}
template <class T> int SeqList<T>::Search(T &x) const {
int i;
for (i = 0; i <= last; i++) {
if (data[i] == x)
return i + 1;
}
return 0;
}
template <class T> int SeqList<T>::Locate(int i) const {
//检验i位置合理性
if (i >= 1 && i <= last + 1)
return i;
else
return 0;
}
template <class T>
bool SeqList<T>::Insert(
int i,
T &x) {
// i∈[0,last+1],0即在第一个元素位置插入,last+1在最后一个元素后插入,即data[i]这个位置
if (i < 0 || i > last + 1)
return false; //数不正确
if (last + 1 >= maxsize)
return false; //超界
for (int k = last; k >= i; k--) {
data[k + 1] = data[k];
}
data[i] = x;
last++;
return true;
}
template <class T> bool SeqList<T>::Remove(int i, T &x) {
if (last == -1)
return false;
if (i < 1 && i > last + 1)
return false;
x = data[i - 1];
for (int k = i - 1; k < last; k++)
data[k] = data[k + 1];
last--;
return true;
}
template <class T> void SeqList<T>::input() {
cout << "please enter the number of data:" << endl;
while (1) {
cin >> last;
if (last + 1 <= maxsize)
break;
cout << "the number is too big,please enter a right number of data:"
<< endl;
}
cout << "please enter " << last + 1 << " data" << endl;
for (int k = 0; k <= last; k++)
cin >> data[k];
}
template <class T> void SeqList<T>::output() {
cout << "output all number:" << endl;
for (int k = 0; k <= last; k++)
cout << k << ":" << data[k] << endl;
}
链表(含头结点)
结构体
这里参照书本,仍采用了类外结构体定义节点
template <class T> struct Linknode {
T data;
Linknode<T> *next;
Linknode(Linknode<T> *p = NULL) {
next = p; }
Linknode(T &item, Linknode<T> *p = NULL) {
data = item, next = p; }
};
list类
template <class T> class List : public LinearList<T> {
//
protected:
Linknode<T> *first;
public:
List() {
first = new Linknode<T>; } //构造函数,建立头结点
List(const T &x) {
first = new Linknode<T>(x);
} //构造函数,建立无头结点,有第一个节点
List(List<T> &L);
void makeempty(); //释放空间的函数
~List() {
makeempty(); } //析构函数
int Lenth() const; //表长
int Size() const {
cout << "budediaoyong" << endl;
return 0;
}
int Locate(int i) const {
cout << "budediaoyong" << endl;
return 0;
}
bool Isfull() {
cout << "budediaoyong" << endl;
return false;
}
int Search(T &x) const; //在表中搜索x;
Linknode<T> *Locatep(int i) const; //定位i;
T getdata(int i) const; //获得第i个值
void setdata(int i, T &x); //修改第i个位置值为x
bool Insert(int i, T &x); //在第i个元素之后的位置插入x
bool Remove(int i, T &x); //删除i的值,通过x返回
bool Isempty() {
return (first->next == NULL) ? true : false; } //表空
void input(); //表输入
void output(); //表输出
// SeqList<T> operator=(SeqList<T> &L) ; //表复制 感觉没必要
};
template <class T> List<T>::List(List<T> &L) {
//逐个节点复制
T value;
Linknode<T> *cur1 = L.Locatep(0);
Linknode<T> *cur2 = first;
while (cur1->next != NULL) {
value = cur1->next->data;
Linknode<T> *newcur = new Linknode<T>(value);
cur2->next = newcur;
cur2 = cur2->next;
cur1 = cur1->next;
}
}
template <class T> void List<T>::makeempty() {
Linknode<T> *del;
while (first->next) {
del = first->next;
first->next = del->next;
delete del;
}
}
template <class T> int List<T>::Lenth() const {
Linknode<T> *cur = first->next;
int count = 0;
while (cur) {
count++;
cur = cur->next;
}
return count;
}
template <class T>
int List<T>::Search(T &x) const {
//搜索成功返回数据位置,否则返回0
Linknode<T> *cur = first->next;
int count = 0;
while (cur != NULL) {
count++;
if (cur->data == x) {
break;
}
cur = cur->next;
}
return count;
}
template <class T>
Linknode<T> *List<T>::Locatep(int i) const {
//返回i个节点的指针,0为头结点
if (i < 0)
return NULL;
Linknode<T> *cur = first;
for (int k = 0; k < i; k++)
cur = cur->next;
return cur;
}
template <class T> T List<T>::getdata(int i) const {
//获得第i个值
Linknode<T> *cur = Locatep(i);
if (cur == NULL || i == 0) {
//头结点为空节点
cout << "chazhaobudao" << endl;
return 0;
} else
return cur->data;
}
template <class T> void List<T>::setdata(int i, T &x) {
Linknode<T> *cur = Locatep(i);
if (cur == NULL || i == 0) {
cout << "chazhaobudao" << endl;
return;
} else
cur->data = x;
}
template <class T> bool List<T>::Insert(int i, T &x) {
Linknode<T> *cur = Locatep(i);
if (cur == NULL) {
cout << "chazhaobudao" << endl;
return false;
}
Linknode<T> *temp = new Linknode<T>(x);
if (temp == NULL) {
cerr << "no space" << endl;
exit(1);
}
temp->next = cur->next;
cur->next = temp;
return true;
}
template <class T> bool List<T>::Remove(int i, T &x) {
Linknode<T> *cur = Locatep(i - 1);
Linknode<T> *temp = cur->next;
if (cur == NULL || temp == NULL) {
cout << "chazhaobudao" << endl;
return false;
}
x = temp->data;
cur->next = temp->next;
delete temp;
return true;
}
template <class T> void List<T>::input() {
cout << "please enter the number of data:" << endl;
int k;
cin >> k;
T x;
cout << "please enter " << k << " data" << endl;
Linknode<T> *cur = first;
for (int j = 0; j < k; j++) {
cin >> x;
Linknode<T> *newcur = new Linknode<T>(x);
cur->next = newcur;
cur = cur->next;
}
}
template <class T> void List<T>::output() {
Linknode<T> *cur = first->next;
while (cur) {
cout << cur->data << ' ';
cur = cur->next;
}
}