数据结构顺序表——线性表实现
2017-11-20 12:34
417 查看
数据结构作业,做代码保存
#include<string.h> #include<ctype.h> #include<malloc.h> // malloc()等 #include<limits.h> // INT_MAX等 #include<stdio.h> // EOF(=^Z或F6),NULL #include<stdlib.h> // atoi() #include<io.h> // eof() #include<math.h> // floor(),ceil(),abs() #include<process.h> // exit() #include<iostream> // cout,cin using namespace std; // 函数结果状态代码 #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 // #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行 typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等 typedef int Boolean; // Boolean是布尔类型,其值是TRUE或FALSE typedef int ElemType; //线性表的动态分配顺序存储结构 #define LIST_INIT_SIZE 10 // 线性表存储空间的初始分配量 #define LISTINCREMENT 2 // 线性表存储空间的分配增量 struct SqList { ElemType *elem; // 存储空间基址 int length; // 当前长度 int listsize; // 当前分配的存储容量(以sizeof(ElemType)为单位) }; //顺序表示的线性表的基本操作(12个) Status InitList(SqList &L) /// 初始化顺序表 { // 操作结果:构造一个空的顺序线性表 L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType)); if(!L.elem) exit(OVERFLOW); // 存储分配失败 L.length=0; // 空表长度为0 L.listsize=LIST_INIT_SIZE; // 初始存储容量 *L.elem=0;///初始化了第一个元素 return OK; } Status DestroyList(SqList &L)///销毁顺序表 { // 初始条件:顺序线性表L已存在。操作结果:销毁顺序线性表L free(L.elem); L.elem=NULL; L.length=0; L.listsize=0; return OK; } Status ClearList(SqList &L)///将顺序表重置为空表 { // 初始条件:顺序线性表L已存在。操作结果:将L重置为空表 L.length=0; return OK; } Status ListEmpty(SqList L)///判断是否为空表 { // 初始条件:顺序线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE return L.length?FALSE:TRUE; } int ListLength(SqList L)///返回线性表元素个数 { // 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数 return L.length; } Status GetElem(SqList L,int i,ElemType &e)///获取线性表中第i个元素 { // 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) // 操作结果:用e返回L中第i个数据元素的值 if(i<1||i>L.length) exit(ERROR); e=*(L.elem+i-1); return OK; } int LocateElem(SqList L,ElemType e,Status(*compare)(ElemType,ElemType))///按compare()位序返回元素 { // 初始条件:顺序线性表L已存在,compare()是数据元素判定函数(满足为1,否则为0) // 操作结果:返回L中第1个与e满足关系compare()的数据元素的位序。 // 若这样的数据元素不存在,则返回值为0。 int i=1; ElemType *p=L.elem; while(i<=L.length&&!(*compare)(*p++,e))++i; if(i<=L.length)return i; else return 0; } Status PriorElem(SqList L,ElemType cur_e,ElemType &pre_e)///返回cur_e元素的前驱元素 { // 初始条件:顺序线性表L已存在 // 操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱, // 否则操作失败,pre_e无定义 int i=2; ElemType *p=L.elem+1; while(i<=L.length&&*p!=cur_e) { p++; i++; } if(i>L.length) return INFEASIBLE; else { pre_e=*--p; return OK; } } Status NextElem(SqList L,ElemType cur_e,ElemType &next_e)///返回cur_e元素的后继元素 { // 初始条件:顺序线性表L已存在 // 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继, // 否则操作失败,next_e无定义 int i=1; ElemType *p=L.elem; while(i<=L.length&&*p!=cur_e) { p++; i++; } if(i>L.length-1) return INFEASIBLE; else { next_e=*++p; return OK; } } Status ListInsert(SqList &L,int i,ElemType e) ///插入元素 { // 初始条件:顺序线性表L已存在,1≤i≤ListLength(L)+1 // 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 if(i<1||i>L.length+1)return ERROR; if(L.length>=L.listsize) { ElemType *newbase=(ElemType *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType)); if(!newbase)exit(OVERFLOW); L.elem=newbase; L.listsize+=LISTINCREMENT; } ElemType *q=&(L.elem[i-1]); for(ElemType *p=&(L.elem[L.length-1]); p>=q; --p) *(p+1)=*p; *q=e; L.length++; return OK; } Status ListDelete(SqList &L,int i,ElemType &e) ///删除元素 { // 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) // 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1 if((i<1)||(i>L.length))return ERROR; ElemType *p=&(L.elem[i-1]); e=*p; ElemType *q=L.elem+L.length-1; for(++p; p<=q; ++p) *(p-1)=*p; L.length--; return OK; } Status ListTraverse(SqList L,void(*vi)(ElemType&))///依次对L的每个数据元素调用函数vi() { // 初始条件:顺序线性表L已存在 // 操作结果:依次对L的每个数据元素调用函数vi()。一旦vi()失败,则操作失败 // vi()的形参 加'&',表明可通过调用vi()改变元素的值 ElemType *p; int i; p=L.elem; for(i=1; i<=L.length; i++) vi(*p++); cout<<endl;//相当于c语言里面的printf("\n") return OK; } ///*==========================================================================================*/ void InsertAscend(SqList &L,ElemType e)///按非严格递增插入元素 { // 初始条件:按非降序排列的顺序线性表L已存在 // 操作结果:在L中按非降序插入新的数据元素e,L的长度加1 int j; for(j=0; j<L.length; j++) if(e<=*(L.elem+j)) break; ListInsert(L,j+1,e); } void InsertDescend(SqList &L,ElemType e)///按非严格递减插入元素 { // 初始条件:按非升序排列的顺序线性表L已存在 // 操作结果:在L中按非升序插入新的数据元素e,L的长度加1 int j; for(j=0; j<L.length; j++) if(e>=*(L.elem+j)) break; ListInsert(L,j+1,e); } Status HeadInsert(SqList &L,ElemType e)///在顺序表L 头部 插入新元素 { // 初始条件:顺序线性表L已存在。操作结果:在L的头部插入新的数据元素e,L的长度加1 ElemType *p,*q,*newbase; if(L.length>=L.listsize) { if(!(newbase=(ElemType *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType)))) exit(OVERFLOW); L.elem=newbase; L.listsize+=LISTINCREMENT; } q=L.elem; for(p=L.elem+L.length-1; p>=q; --p) *(p+1)=*p; *q=e; L.length++; return OK; } Status EndInsert(SqList &L,ElemType e)///在顺序表L 尾部 插入新元素 { // 初始条件:顺序线性表L已存在。操作结果:在L的尾部插入新的数据元素e,L的长度加1。 ElemType *p,*q,*newbase; if(L.length>=L.listsize) { if(!(newbase=(ElemType *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType)))) exit(OVERFLOW); L.elem=newbase; L.listsize+=LISTINCREMENT; } q=L.elem+L.length; *q=e; L.length++; return OK; } Status DeleteFirst(SqList &L,ElemType &e)///删除顺序表中第一个元素 { // 初始条件:顺序线性表L已存在,且有不少于1个元素 // 操作结果:删除L的第一个数据元素,并由e返回其值,L的长度减1 ElemType *p,*q; if(!L.length) return ERROR; p=L.elem;///首地址也是第一个元素的的地址,用指针存储 e=*p;///e作为一个元素,应是指针p指向的元素 q=L.elem+L.length-1; for(++p; p<=q; ++p) *(p-1)=*p; L.length--; return OK; } Status DeleteTail(SqList &L,ElemType &e)///删除顺序表中最后一个元素 { // 初始条件:顺序线性表L已存在,且有不少于1个元素 // 操作结果:删除L的最后一个数据元素,并用e返回其值,L的长度减1 ElemType *p; if(!L.length) // 空表 return ERROR; p=L.elem+L.length-1; // 最后一个数据元素的位置 e=*p; // 被删除元素的值赋给e L.length--; // 表长减1 return OK; } Status DeleteElem(SqList &L,ElemType e) { // 删除表中值为e的元素,并返回TRUE;如无此元素,则返回FALSE ElemType *p; int flag=0; for(p=L.elem; p<=L.elem+L.length-1; p++) { if(*p==e) { flag=1; ElemType *q=L.elem+L.length-1; ElemType *P=p; for(++P; P<=q; ++P) *(P-1)=*P; L.length--; p--; } } return flag?TRUE:FALSE; } Status ReplaceElem(SqList L,int i,ElemType e) { // 用e取代表L中第i个元素的值 if(i<1||i>L.length) exit(ERROR); *(L.elem+i-1)=e; return OK; } Status CreatAscend(SqList &L,int n)///非严格递增顺序建表 { // 按非降序建立n个元素的线性表 int i,j; ElemType e; InitList(L); printf("请输入%d个元素:\n",n); cin>>e; ListInsert(L,1,e); // 在空表中插入第1个元素 for(i=1; i<n; i++) { cin>>e; for(j=0; j<L.length; j++) if(e<=*(L.elem+j)) break; ListInsert(L,j+1,e); // 插于表中 } return TRUE; } Status CreatDescend(SqList &L,int n)///非严格递减顺序建表 { // 按非升序建立n个元素的线性表 int i,j; ElemType e; InitList(L); printf("请输入%d个元素:\n",n); cin>>e; ListInsert(L,1,e); // 在空表中插入第1个元素 for(i=1; i<n; i++) { cin>>e; for(j=0; j<L.length; j++) if(e>=*(L.elem+j)) break; ListInsert(L,j+1,e); // 插于表中 } return TRUE; } ///========================================================================== Status comp(ElemType c1,ElemType c2) /// 数据元素判定函数(平方关系) { if(c1==c2*c2) return TRUE; else return FALSE; } void visit(ElemType &c) /// ListTraverse()调用的函数(类型要一致) { cout<<c<<' '; } void dbl(ElemType &c) /// ListTraverse()调用的另一函数(元素值加倍) { c*=2; } void UNION(SqList &La,SqList Lb)///去重联合顺序表 { ElemType e; for(int i=1; i<=Lb.length; i++) { GetElem(Lb,i,e); if(!LocateElem(La,e,comp)) { ListInsert(La,1+La.length,e);///因为这里我用了线性表的长度直接判断,因此不能像书上一样做自增操作,应该直接+1比较保险 } } } void MergeList(SqList La,SqList Lb,SqList &Lc)///非递减排列顺序表 { InitList(Lc); int i=1,j=1,k=0; int La_len=ListLength(La),Lb_len=ListLength(Lb); ElemType ai,bj; while((i<=La_len)&&(j<=Lb_len)) { GetElem(La,i,ai); GetElem(Lb,j,bj); if(ai<=bj) { ListInsert(Lc,++k,ai); ++i; } else { ListInsert(Lc,++k,bj); ++j; } } while(i<=La_len) { GetElem(La,i++,ai); ListInsert(Lc,++k,ai); } while(j<=Lb_len) { GetElem(Lb,j++,bj); ListInsert(Lc,++k,bj); } } int main() { int num=1; SqList La,Lb,Lc; InitList(La); printf("表La中初始元素:"); for(int i=1; i<=7; i++) { ListInsert(La,num++,i); printf("%d%c",i,i==7?'\n':' '); } InitList(Lb); num=1; printf("表Lb中初始元素:"); for(int i=3; i<=10; i++) { ListInsert(Lb,num++,i); printf("%d%c",i,i==10?'\n':' '); } UNION(La,Lb); printf("合并后表La中元素:"); ElemType e; for(int i=1; i<=La.length; i++) { printf("%d%c",La.elem[i-1],i==La.length?'\n':' '); } printf("\n"); InitList(La),InitList(Lb),InitList(Lc); num=1; printf("表La中初始元素:"); for(int i=1; i<=10; i+=2) { ListInsert(La,num++,i); printf("%d%c",i,i==9?'\n':' '); } num=1; printf("表Lb中初始元素:"); for(int i=2; i<=10; i+=2) { ListInsert(Lb,num++,i); printf("%d%c",i,i==10?'\n':' '); } MergeList(La,Lb,Lc); printf("表Lc归并后有%d个元素\n",Lc.length); printf("归并后Lc中元素:"); for(int i=1; i<=Lc.length; i++) printf("%d%c",Lc.elem[i-1],i==Lc.length?'\n':' '); ///================================================================================= char g='1'; SqList L; ElemType e0; Status i; int j,k; i=InitList(L); printf("初始化L后:L.elem=%u L.length=%d L.listsize=%d\n",*L.elem,L.length,L.listsize); //在L的表头依次插入1~5,并且在屏幕上依次输出5个元素 for(i=1; i<=5; i++) { HeadInsert(L,i); printf("%d%c",i,i==5?'\n':' '); } printf("L.elem=%u L.length=%d L.listsize=%d\n",*L.elem,L.length,L.listsize); i=ListEmpty(L); printf("L是否空:i=%d(1:是 0:否)\n",i); i=ClearList(L); printf("清空L后:L.elem=%u L.length=%d L.listsize=%d\n",*L.elem,L.length,L.listsize); i=ListEmpty(L); printf("L是否空:i=%d(1:是 0:否)\n",i); //在L的表尾依次插入1~10,并且在屏幕上依次输出10个元素 for(i=1; i<=10; i++) { EndInsert(L,i); printf("%d%c",i,i==10?'\n':' '); } printf("L.elem=%u L.length=%d L.listsize=%d\n",*L.elem,L.length,L.listsize); //在L的表头插入0,并且在屏幕上依次输出11个元素 HeadInsert(L,0); for(int i=1; i<=L.length; i++) { GetElem(L,i,e); printf("%d%c",e,i==L.length?'\n':' '); } printf("L.elem=%u(有可能改变) L.length=%d(改变) L.listsize=%d(改变)\n",*L.elem,L.length,L.listsize); // 取线性表中的第5个元素,并且在屏幕上输出 GetElem(L,5,e); printf("%d\n",e); for(j=3; j<=4; j++) { k=LocateElem(L,j,comp); if(k) printf("第%d个元素的值为%d的平方\n",k,j); else printf("没有值为%d的平方的元素\n",j); } for(j=1; j<=2; j++) // 测试头两个数据 { GetElem(L,j,e0); // 把第j个数据赋给e0 i=PriorElem(L,e0,e); // 求e0的前驱 if(i==INFEASIBLE) printf("元素%d无前驱\n",e0); else printf("元素%d的前驱为:%d\n",e0,e); } for(j=ListLength(L)-1; j<=ListLength(L); j++) // 最后两个数据 { GetElem(L,j,e0); // 把第j个数据赋给e0 i=NextElem(L,e0,e); // 求e0的后继 if(i==INFEASIBLE) printf("元素%d无后继\n",e0); else printf("元素%d的后继为:%d\n",e0,e); } k=ListLength(L); // k为表长 for(j=k+1; j>=k; j--) { i=ListDelete(L,j,e); // 删除第j个数据 if(i==ERROR) printf("删除第%d个数据失败\n",j); else printf("删除的元素值为:%d\n",e); } printf("依次输出L的元素:"); ListTraverse(L,visit); // 依次对元素调用visit(),输出元素的值 printf("L的元素值加倍后:"); ListTraverse(L,dbl); // 依次对元素调用dbl(),元素值乘2 ListTraverse(L,visit); DestroyList(L); printf("销毁L后:L.elem=%u L.length=%d L.listsize=%d\n",L.elem,L.length,L.listsize); while(g!='0')scanf("%c",&g); }
相关文章推荐
- (4) 数据结构与算法 ---- 线性表 及Java实现 顺序表、链表、栈、队列
- 数据结构:用顺序表实现栈
- 数据结构顺序表Java实现
- 数据结构(C实现)------- 顺序表
- 数据结构顺序表定义和实现
- 数据结构之单向线性表 c语言与java语言实现
- 数据结构(二)--- 线性表链表(单链表)java实现方式
- 数据结构——线性表——顺序表
- 数据结构(3)--线性表实现一元多项式加法
- 数据结构顺序表实现学习
- 数据结构——Josephus问题顺序表实现
- 线性表-顺序表、链表类模板的实现(数据结构基础 第2周)
- 顺序表.cpp [数据结构实现 之 线性表]
- 数据结构(21)队列--线性表实现
- 数据结构基础之数组实现线性表各种操作
- 数据结构实验1— 线性表、链表的实现
- 数据结构笔记(一)线性表的顺序表示和基本操作及其顺序表实现的集合运算(A-B)U(B-A)实例
- 数据结构—线性表(Java、C双语言实现)
- 数据结构基础之数组实现线性表各种操作(二)
- 数据结构——线性表——顺序存储结构——C++实现线性表