《数据结构与算法》——线性表之顺序表(SqList)总结
2019-07-20 15:21
246 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Kwzc4/article/details/96594791
《数据结构与算法》——线性表之顺序表(SqList)总结
从前天开始着手复习线性表部分,整了3个下午才用C++对顺序表的部分内容进行了成功实现,下面就简单进行以下总结。
目录
定义
线性表:具有线性存储结构的抽象数据类型,它是由n个数据元素组成的有限序列。其中数据元素可以是很多种,int、string、char甚至是自定义类型。
课本上还有个定义是说其他几个名词的关系:若干数据项组成了一条记录(数据元素),含有大量记录的线性表被称为文件。
在书上对抽象数据类型的线性表定义如下图:
线性表分为顺序表和链表,在本文中将对线性表中的顺序表以C++语言的方式,构建SqList类,并对其类方法进行实现。
class SqList
[code]class SqList { private: T *data=NULL;//设置成动态的 int len,Max; int step; public: SqList(int Max , T t );//{//构造函数, int step = 50 void InitList(int Max , T t);//初始化 int length(); int LocateElem(T elem);//按值查找 T GetElem(int i); //按位查找 void ListtInsert(int i ,T elem); void ListDelete(T elem);//删除元素 void PrintList(); bool Empty(); void DestroyList(); void MergeList(SqList lb);//合并两个表,有序 ~ SqList();//析构函数 };
方法实现
[code]/*编译环境: win10专业版 DEV C++ 5.11 TDM-GCC 4.9.2 64bit */ #include<iostream> #include<stdlib.h> using namespace std; #define STEP 50 #define OVERFLOW 0 template <typename T > class SqList { private: T *data=NULL;//设置成动态的 int len,Max; int step; public: SqList(int Max , T t );//{//构造函数, int step = 50 void InitList(int Max , T t);//初始化 int length(); int LocateElem(T elem);//按值查找 T GetElem(int i); //按位查找 void ListtInsert(int i ,T elem); void ListDelete(T elem);//删除元素 void PrintList(); bool Empty(); void DestroyList(); void MergeList(SqList lb);//合并两个表,有序 ~ SqList();//析构函数 }; template <typename T > SqList<T>::SqList(int Max , T t){//构造函数, int step = 50 /* * 初始化最大容量,元素类型&错误标记,步长 */ T *tt = (T*)malloc(sizeof(T)*Max); if(!tt){ cout<<"空间分配失败"<<endl; exit(OVERFLOW);//空间分配失败 } this->data = tt; this->data[0] = t; this->Max = Max; this->len = 0; this->step = STEP; } template <typename T> void SqList<T>::InitList(int Max , T t){//初始化 SqList(Max , t); } template <typename T> int SqList<T>::length(){//返回顺序表长度 return len; } template <typename T> int SqList<T>::LocateElem(T elem){//按值查找 int i = 0; for( ; i<=this->len && data[i]!= elem;i++); if( i <= this->len) return i; return 0;//无此值 } template <typename T> T SqList<T>::GetElem(int i){ //按位查找 if(i<=this->len && i>0 ) return data[i]; return data[0]; } template <typename T> void SqList<T>::ListtInsert(int i ,T elem){//按位插值 if (i==0||i>=this->len+2) return ; if(this->len >= this->Max) {//重新分配内存块 T * Temp = (T *) realloc(this->data, sizeof(T)*(this->Max + this->step)); if (Temp == NULL)// { exit(OVERFLOW);//<<"The memory relloced failed!"<<endl; //} this->data = Temp; this->Max = this->Max + this->step; } this->len ++;//长度增加 int j = this->len ; for( ; j>i ;j--){ this->data[j] = this->data[j-1]; } this->data[j] = elem; } template <typename T> void SqList<T>::ListDelete(T elem){//删除元素 int i=0; while(i<len && this->data[++i]!=elem); if(i==len&&this->data[i]!=elem) return ; else{ while(i<len){ this->data[i] = this 3ff7 ->data[i+1]; i++; } this->len--; } } template <typename T> void SqList<T>::PrintList(){//输出顺序表 cout<<"["; if(len==0) cout<<" "; else{ for(int i = 1 ; i < len ;i++){ cout<<this->data[i]<<" "; } cout<<this->data[len]; } cout<<"]"<<endl; } template <typename T> bool SqList<T>::Empty(){//判空 if(this->len==0) return 1; else return 0; } template <typename T> void SqList<T>::DestroyList(){//销毁顺序表 len=0; free(this->data); this->data = NULL; } template <typename T> void SqList<T>::MergeList(SqList<T> lb){//合并两个顺序表 /* *分为两种情况,有序和无序,无序直接合并,有序则按序合并 */ int i=0,j=0; bool flag = 1; while(((++i)<this->len) && (this->data[i] <= this->data[i+1]) );//判断当前字符串是否有序 if((i <= this->len) && (this->data[this->len] < this->data[this->len-1]) )//无序 flag = 0 ; else{ while(((++j) < lb.len) && (lb.data[j] <= lb.data[j+1]) );//判断合并字符串是否有序 if((j == lb.len) && (lb.data[j] >= lb.data[j-1]) )//有序 flag = 1 ;//有序 else flag = 0 ; //无序 } if(flag){//有序 T * Temp = (T *) malloc(sizeof(T)*(this->Max)); int len = this->len,j=1,k=1,l=1; if (!Temp) exit(OVERFLOW); while(j<=len)//辅助数组 Temp[j]= this->data[j++]; if(this->Max < this->len + lb.len ){//空间不足 //对A扩充空间 T *tem = (T*) realloc(this->data, sizeof(T)*(this->Max + lb.Max)); if (!tem) //exit(OVERFLOW); this->data = tem ; flag=0; } else flag = 1; //比较大小合并 j = 1; while(j<=len && k<=lb.len) if(Temp[j] <= lb.data[k]) this->data[l++] = Temp[j++]; else this->data[l++] = lb.data[k++]; while(j<=len) this->data[l++] = Temp[j++]; while(k<=lb.len) this->data[l++] = lb.data[k++]; } else{//无序 T * Temp = (T*) realloc(this->data, sizeof(T)*(this->Max + lb.Max)); lb.PrintList(); if (!Temp) exit(OVERFLOW); this->data = Temp; j=1; while(j<=lb.len){ this->data[len+j] = lb.data[j++]; } } this->Max = flag?this->Max :this->Max + lb.Max; this->len = this->len + lb.len; } template <typename T> SqList<T>::~SqList(){//析构 len=0; free(this->data); this->data = NULL; } int main() { SqList<int> l(50,-1); cout<<"初始化:"; l.PrintList(); l.ListtInsert(1,6); cout<<"在第1位插入6:";l.PrintList(); l.ListtInsert(2,8); cout<<"在第2位插入8:";l.PrintList(); l.ListtInsert(2,7); cout<<"在第2位插入7:";l.PrintList(); l.ListtInsert(4,9);l.ListtInsert(1,5); l.ListtInsert(1,4);l.ListtInsert(1,3); l.ListtInsert(1,2);l.ListtInsert(1,1); cout<<"在插入很多数据后:";l.PrintList(); cout<<"当前表长度为:"<<l.length()<<endl; l.ListDelete(4); cout<<"删除元素4:"; l.PrintList(); cout<<"查询第6个元素是:"<<l.GetElem(6)<<endl; cout<<"查询元素6的位置为:"<<l.LocateElem(6)<<endl; //新建一个顺序表 SqList<int> l2(50,-1); l2.ListtInsert(1,6);l2.ListtInsert(1,5);l2.ListtInsert(1,4); l2.ListtInsert(1,3);l2.ListtInsert(1,2);l2.ListtInsert(1,1); cout<<"l2有序初始化:"; l2.PrintList(); l.MergeList(l2); cout<<"l与l2合并结果:"; l.PrintList(); //新建一个顺序表 SqList<int> l3(50,-1); l3.ListtInsert(1,9);l3.ListtInsert(1,8);l3.ListtInsert(1,5); l3.ListtInsert(1,7);l3.ListtInsert(1,4);l3.ListtInsert(1,2); cout<<"l3无序初始化:"; l3.PrintList(); l.MergeList(l3); cout<<"l与l3合并结果:"; l.PrintList(); l3.DestroyList(); cout<<"销毁l3:"; l3.PrintList(); return 0; }
错误
在代码实现的过程中,采用了模板类+外联函数的方式,主要是为了达到C++和数据结构同时复习的目的。但在过程中以下代码总是报错:
[code]template <typename T , int step=50 > class SqList { private: T *data=NULL;//设置成动态的 int len,Max; int step; public: SqList(int Max , T t );//{//构造函数, int step = 50 ...... }; template <typename T,int step = 50 > SqList<T>::SqList(int Max , T t){//构造函数, int step = 50 T *tt = (T*)malloc(sizeof(T)*Max); if(!tt){ cout<<"空间分配失败"<<endl; exit(OVERFLOW);//空间分配失败 } this->data = tt; this->data[0] = t; this->Max = Max; this->len = 0; this->step = step; } //错误: /* [Error] invalid use of incomplete type 'class SqList<T>' *[Error] declaration of 'class SqList<T>' *原因? */
将其改为内联函数错误便消失,但是就想用外联函数,找原因也不知个所以然,所以就将其中的默认参数给删掉了,解决了问题。如下:
[code]template <typename T > class SqList { private: T *data=NULL;//设置成动态的 int len,Max; int step; public: SqList(int Max , T t );//{//构造函数, int step = 50 ...... }; template <typename T> SqList<T>::SqList(int Max , T t){//构造函数, int step = 50 T *tt = (T*)malloc(sizeof(T)*Max); if(!tt){ cout<<"空间分配失败"<<endl; exit(OVERFLOW);//空间分配失败 } this->data = tt; this->data[0] = t; this->Max = Max; this->len = 0; this->step = STEP;//宏定义STEP }
难点
对于“数据结构”这一部分学习的难点,我认为一是对实际问题进行抽象化处理,二是对数据结构实现时的不熟练,这部分应归结于语言和编程能力的不足。
参考文献
严蔚敏,吴伟民. 数据结构(C语言版)[M]. 北京: 清华大学出版社,2013.
如有错误,还请朋友不吝指正。
相关文章推荐
- 数据结构与算法学习总结-线性表的顺序存储与实现
- 数据结构与算法入门1-线性表的顺序存储
- 线性表学习归纳总结二:线性表顺序存储实现
- 实验二总结(比较线性表的顺序表与链表)
- 数据结构总结 (一)------线性表之顺序表
- 数据结构与算法--线性表(顺序表)
- 8. C#数据结构与算法 -- 线性存储结构(线性表之顺序表,数组实现)
- 数据结构与算法 1 :基本概念,线性表顺序结构,线性表链式结构,单向循环链表
- 数据结构与算法(二)-线性表之单链表顺序存储和链式存储
- 《线性表的总结---线性顺序表(静态,动态)---线性链表(动态)》
- 学习 线性表的顺序存储 总结一
- 数据结构与算法Java版——线性顺序表的实现
- 数据结构与算法总结1_常用的数据结构(线性表)
- C++ 数据结构与算法(一)线性表之顺序表
- 线性表之<顺序表sqlist>的储存及插入、删除-C代码实现
- 9. C#数据结构与算法 -- 线性存储结构(线性表之顺序表,动态数组和泛型实现)
- 《数据结构与算法》——线性表之链表(LinkList)总结
- 数据结构与算法(二)线性表的顺序表示
- 数据结构与算法(线性表_顺序表存储结构)
- 线性表学习之顺序表示