线性表的顺序存储与实现
来源:互联网 发布:tensorflow linux 推荐 编辑:程序博客网 时间:2024/05/01 12:23
线性表的顺序存储与实现
线性表的顺序存储是指在内存中用一组地址连续的存储单元一次存储线性表的各元素,用这种存储形式存储的线性表称为顺序表。
之前没看书的时候还以为线性表的顺序存储指的是结构体数组,后来看了下书发现是一个含有数组的结构体,其实我个人觉得结构体数组比较好用,含有数组的结构体和数组的区别不大,只是多了对数组信息的存储。
下面先介绍顺序表吧(以存储的数据为整数为例 typedef int ElemType):
定义顺序表的类型
#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量#define LISTINCREMENT 10 //线性表存储空间的分配增量typedef int ElemType;typedef struct{ ElemType *elem; //存储空间基址 int length; //当前长度 int listsize; //当前分配的存储容量(以sizeof(ElemType)为单位)}SqList;
1、线性表的初始化(InitList_Sq)
Status InitList_Sq(SqList *L){ L->elem = (int*)malloc(LIST_INIT_SIZE * sizeof(ElemType)); if(!L->elem) return ERROR; L->length = 0; L->listsize = LIST_INIT_SIZE; return OK;}
2、线性表的查找操作(LocateElem_Sq)
int LocateElem_Sq(SqList L, ElemType e){ /*顺序表L已经存在,返回L中第1个与e相等的数据元素的位序*/ /*若这样的数据元素不存在,则返回值为0*/ ElemType *p; int i = 1; //i的初值为第1个元素的位序 p = L.elem; //p的初值为第1个元素的存储位置 while(i <= L.length && (*p++) != e) /*并非所有元素都可以使用(*p++) != e判断是否相等*/ ++i; if(i <= L.length) return i; else return 0;}
3、线性表的插入操作
Status ListInsert_Sq(SqList *L, int i, ElemType e){ /*顺序表L已存在,当 1<=i<=ListLength(L)+1 时,在L中第i个位置之前插入新的数据 元素e,L的长度增1*/ ElemType *newbase; int j; if(i < 1 || i > L->length+1) //判断i值是否合法 return ERROR; if(L->length >= L->listsize){ //当前存储空间已满,增加分配 newbase = (ElemType*)realloc((*L).elem, ((*L).listsize+LISTINCREMENT)*sizeof(ElemType)); if(!newbase) return ERROR; L->elem = newbase; L->listsize = L->listsize + LISTINCREMENT; } for(j = (L->length)-1; j >= i-1; j--) L->elem[j+1] = L->elem[j]; L->elem[i-1] = e; ++L->length; return OK;}
4、线性表的删除操作
ElemType ListDelete_Sq(SqList *L, int i){ /*删除顺序表L中的第i个(1<=i<=ListLength(L))数据元素,并用e返回其值,L的长度减1*/ int j; ElemType e; if(i < 1 || i > L->length) //判断i值是否合法 return ERROR; e = L->elem[i-1]; for(j = i; j < L->length; j++) L->elem[j-1] = L->elem[j]; L->length--; return e;}
5、两个集合的并集
void Union_Sq(SqList *La, SqList *Lb) //集合的合并操作{ /*将所有在线性表Lb中但不在La中的数据元素依次插入到La中*/ int e; int La_len, Lb_len; int i; La_len = La->length, Lb_len = Lb->length; for(i = 1; i <= Lb_len; i++){ e = Lb->elem[i-1]; if(!LocateElem_Sq(*La,e)) ListInsert_Sq(La, ++La_len, e); } }
6、两个有序表的合并
void MergeList_Sq(SqList La, SqList Lb, SqList *Lc){ /*已知线性表La和Lb中的数据元素按值非递减排列*/ /*归并La和Lb得到新的线性表Lc,Lc的数据元素也按值非递减排列*/ int i = 0, j = 0, k = 1; int ai,bj; InitList_Sq(Lc); while(i <= La.length-1 && j <= Lb.length-1){ ai = La.elem[i]; bj = Lb.elem[j]; if(ai <= bj){ ListInsert_Sq(Lc,k,ai); i++; k++; } else{ ListInsert_Sq(Lc,k,bj); j++; k++; } } while(i <= La.length-1){ ai = La.elem[i]; ListInsert_Sq(Lc, k, ai); i++; k++; } while(j <= Lb.length-1){ bj = Lb.elem[j]; ListInsert_Sq(Lc, k, bj); j++; k++; }}
全部代码
#include <stdio.h>#include <stdlib.h>#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define OVERFLOW -2typedef int Status;typedef int Boolean;#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量#define LISTINCREMENT 10 //线性表存储空间的分配增量typedef int ElemType;typedef struct{ ElemType *elem; //存储空间基址 int length; //当前长度 int listsize; //当前分配的存储容量(以sizeof(ElemType)为单位)}SqList;Status InitList_Sq(SqList *L);int LocateElem_Sq(SqList L,ElemType e);Status ListInsert_Sq(SqList *L,int i,ElemType e);ElemType ListDelete_Sq(SqList *L, int i);void Union_Sq(SqList *La, SqList *Lb);void MergeList_Sq(SqList La, SqList Lb, SqList *Lc);void Print_Sq(SqList L);int main(void){ SqList La; int i,j,k,n; InitList_Sq(&La); printf("请输入元素个数:"); scanf("%d",&n); printf("请输入元素: "); for(i = 0; i < n; i++){ scanf("%d",&j); if(!ListInsert_Sq(&La, La.length+1, j)){ printf("空间分配失败!\n"); exit(OVERFLOW); } } printf("输入的元素为: "); Print_Sq(La); printf("请输入要插入的值及其插入到第几个元素之前: "); scanf("%d%d",&i,&j); ListInsert_Sq(&La, j, i); Print_Sq(La); printf("请输入要删除第几个元素:"); scanf("%d",&i); k = ListDelete_Sq(&La, i); printf("删除的元素的值为 %d\n", k); Print_Sq(La); SqList Lb, Lc; InitList_Sq(&Lb); printf("请再输入一组元素: "); for(i = 0; i < n; i++){ scanf("%d",&j); if(!ListInsert_Sq(&Lb, Lb.length+1, j)){ printf("空间分配失败!\n"); exit(OVERFLOW); } } printf("输入的元素为: "); Print_Sq(Lb); printf("将第二组有且第一组没有的元素合并到第一组: "); Union_Sq(&La, &Lb); Print_Sq(La); free(La.elem); free(Lb.elem); InitList_Sq(&La); InitList_Sq(&Lb); InitList_Sq(&Lc); printf("请再输入两组非降序元素:\n"); printf("第一组: "); for(i = 0; i < n; i++){ scanf("%d",&j); if(!ListInsert_Sq(&La, La.length+1, j)){ printf("空间分配失败!\n"); exit(OVERFLOW); } } printf("第二组: "); for(i = 0; i < n; i++){ scanf("%d",&j); if(!ListInsert_Sq(&Lb, Lb.length+1, j)){ printf("空间分配失败!\n"); exit(OVERFLOW); } } MergeList_Sq(La, Lb, &Lc); printf("按序合并为: "); Print_Sq(Lc); return 0;}Status InitList_Sq(SqList *L){ L->elem = (int*)malloc(LIST_INIT_SIZE * sizeof(ElemType)); if(!L->elem) return ERROR; L->length = 0; L->listsize = LIST_INIT_SIZE; return OK;}int LocateElem_Sq(SqList L, ElemType e){ /*顺序表L已经存在,返回L中第1个与e相等的数据元素的位序*/ /*若这样的数据元素不存在,则返回值为0*/ ElemType *p; int i = 1; //i的初值为第1个元素的位序 p = L.elem; //p的初值为第1个元素的存储位置 while(i <= L.length && (*p++) != e) /*并非所有元素都可以使用(*p++) != e判断是否相等*/ ++i; if(i <= L.length) return i; else return 0;}Status ListInsert_Sq(SqList *L, int i, ElemType e){ /*顺序表L已存在,当 1<=i<=ListLength(L)+1 时,在L中第i个位置之前插入新的数据 元素e,L的长度增1*/ ElemType *newbase; int j; if(i < 1 || i > L->length+1) //判断i值是否合法 return ERROR; if(L->length >= L->listsize){ //当前存储空间已满,增加分配 newbase = (ElemType*)realloc((*L).elem, ((*L).listsize+LISTINCREMENT)*sizeof(ElemType)); if(!newbase) return ERROR; L->elem = newbase; L->listsize = L->listsize + LISTINCREMENT; } for(j = (L->length)-1; j >= i-1; j--) L->elem[j+1] = L->elem[j]; L->elem[i-1] = e; ++L->length; return OK;}ElemType ListDelete_Sq(SqList *L, int i){ /*删除顺序表L中的第i个(1<=i<=ListLength(L))数据元素,并用e返回其值,L的长度减1*/ int j; ElemType e; if(i < 1 || i > L->length) //判断i值是否合法 return ERROR; e = L->elem[i-1]; for(j = i; j < L->length; j++) L->elem[j-1] = L->elem[j]; L->length--; return e;}void Union_Sq(SqList *La, SqList *Lb) //集合的合并操作{ /*将所有在线性表Lb中但不在La中的数据元素依次插入到La中*/ int e; int La_len, Lb_len; int i; La_len = La->length, Lb_len = Lb->length; for(i = 1; i <= Lb_len; i++){ e = Lb->elem[i-1]; if(!LocateElem_Sq(*La,e)) ListInsert_Sq(La, ++La_len, e); } }void MergeList_Sq(SqList La, SqList Lb, SqList *Lc){ /*已知线性表La和Lb中的数据元素按值非递减排列*/ /*归并La和Lb得到新的线性表Lc,Lc的数据元素也按值非递减排列*/ int i = 0, j = 0, k = 1; int ai,bj; InitList_Sq(Lc); while(i <= La.length-1 && j <= Lb.length-1){ ai = La.elem[i]; bj = Lb.elem[j]; if(ai <= bj){ ListInsert_Sq(Lc,k,ai); i++; k++; } else{ ListInsert_Sq(Lc,k,bj); j++; k++; } } while(i <= La.length-1){ ai = La.elem[i]; ListInsert_Sq(Lc, k, ai); i++; k++; } while(j <= Lb.length-1){ bj = Lb.elem[j]; ListInsert_Sq(Lc, k, bj); j++; k++; }}void Print_Sq(SqList L){ int i; for(i = 0; i < L.length; i++) printf("%d ", L.elem[i]); printf("\n");}
运行结果
总结
其实顺序表就是一个记录长度,并且是动态分配空间的数组,个人觉得结构体数组以及链表的作用会更大一些。
更新(改善了交互性及容错性)
全部代码
#include <stdio.h>#include <stdlib.h>#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define OVERFLOW -2typedef int Status;typedef int Boolean;#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量#define LISTINCREMENT 10 //线性表存储空间的分配增量typedef int ElemType;typedef struct{ ElemType *elem; //存储空间基址 int length; //当前长度 int listsize; //当前分配的存储容量(以sizeof(ElemType)为单位)}SqList;Status InitList_Sq(SqList *L);int LocateElem_Sq(SqList L, ElemType e);Status Find_Sq(SqList L, int i, ElemType *e);Status ListInsert_Sq(SqList *L, int i, ElemType e);ElemType ListDelete_Sq(SqList *L, int i, ElemType *e);void Union_Sq(SqList *La, SqList *Lb);void MergeList_Sq(SqList La, SqList Lb, SqList *Lc);void Print_Sq(SqList L);void Print_Hyphen(int n);int main(void){ SqList La,Lb,Lc; int end = 0,opt = 0; int i,j,k,n; Print_Hyphen(5); printf("线性表的顺序存储与实现示例"); Print_Hyphen(5); printf("\n"); InitList_Sq(&La); printf("请输入元素个数:"); scanf("%d",&n); printf("请输入元素: "); for(i = 0; i < n; i++){ scanf("%d",&j); if(!ListInsert_Sq(&La, La.length+1, j)){ printf("空间分配失败!\n"); exit(OVERFLOW); } } printf("输入的元素为: "); Print_Sq(La); while(!end){ Print_Hyphen(15); printf("\n"); Print_Hyphen(5); printf("功能列表"); Print_Hyphen(5); printf("\n"); printf("1、输入序号查找元素\n2、输入元素查找序号\n3、插入元素\n"); printf("4、删除元素\n5、求两组元素的并集\n6、按序合并两个非递减序列\n"); printf("7、退出演示\n"); Print_Hyphen(15); printf("\n"); printf("输入要使用的功能的序号: "); scanf("%d",&opt); Print_Hyphen(15); printf("\n"); switch(opt){ case 1: int find; printf("请输入要查找元素的序号: "); scanf("%d",&find); if(Find_Sq(La, find, &k)) printf("元素为:%d\n", k); else printf("输入的序号不合法!"); break; case 2: ElemType findLoc; printf("请输入要获得序号的元素: "); scanf("%d",&findLoc); if(LocateElem_Sq(La, findLoc) == 0) printf("未找到此元素\n"); else printf("序号为:%d\n",LocateElem_Sq(La, findLoc)); break; case 3: printf("请输入要插入的值及其插入到第几个元素之前: "); scanf("%d%d",&i,&j); ListInsert_Sq(&La, j, i); Print_Sq(La); break; case 4: printf("请输入要删除第几个元素:"); scanf("%d",&i); if(ListDelete_Sq(&La, i, &k)) printf("删除的元素的值为 %d\n", k); else printf("输入的序号不合法!"); Print_Sq(La); break; case 5: InitList_Sq(&Lb); printf("请再输入一组元素: "); for(i = 0; i < n; i++){ scanf("%d",&j); if(!ListInsert_Sq(&Lb, Lb.length+1, j)){ printf("空间分配失败!\n"); exit(OVERFLOW); } } printf("输入的元素为: "); Print_Sq(Lb); printf("将第二组有且第一组没有的元素合并到第一组: "); Union_Sq(&La, &Lb); Print_Sq(La); free(La.elem); free(Lb.elem); break; case 6: InitList_Sq(&La); InitList_Sq(&Lb); InitList_Sq(&Lc); printf("请再输入两组非降序元素:\n"); printf("第一组: "); for(i = 0; i < n; i++){ scanf("%d",&j); if(!ListInsert_Sq(&La, La.length+1, j)){ printf("空间分配失败!\n"); exit(OVERFLOW); } } printf("第二组: "); for(i = 0; i < n; i++){ scanf("%d",&j); if(!ListInsert_Sq(&Lb, Lb.length+1, j)){ printf("空间分配失败!\n"); exit(OVERFLOW); } } MergeList_Sq(La, Lb, &Lc); printf("按序合并为: "); Print_Sq(Lc); break; case 7: printf("再见!\n"); end = 1; break; default: printf("无此序号,请重新输入!\n"); } } return 0;}Status InitList_Sq(SqList *L){ L->elem = (int*)malloc(LIST_INIT_SIZE * sizeof(ElemType)); if(!L->elem) return ERROR; L->length = 0; L->listsize = LIST_INIT_SIZE; return OK;}int LocateElem_Sq(SqList L, ElemType e){ /*顺序表L已经存在,返回L中第1个与e相等的数据元素的位序*/ /*若这样的数据元素不存在,则返回值为0*/ ElemType *p; int i = 1; //i的初值为第1个元素的位序 p = L.elem; //p的初值为第1个元素的存储位置 while(i <= L.length && (*p++) != e) /*并非所有类型的元素都可以使用(*p++) != e判断是否相等*/ ++i; if(i <= L.length) return i; else return 0;}Status Find_Sq(SqList L, int i, ElemType *e){ if(i < 1 || i > L.length) return ERROR; *e = L.elem[i-1]; return OK;}Status ListInsert_Sq(SqList *L, int i, ElemType e){ /*顺序表L已存在,当 1<=i<=ListLength(L)+1 时,在L中第i个位置之前插入新的数据 元素e,L的长度增1*/ ElemType *newbase; int j; if(i < 1 || i > L->length+1) //判断i值是否合法 return ERROR; if(L->length >= L->listsize){ //当前存储空间已满,增加分配 newbase = (ElemType*)realloc((*L).elem, ((*L).listsize+LISTINCREMENT)*sizeof(ElemType)); if(!newbase) return ERROR; L->elem = newbase; L->listsize = L->listsize + LISTINCREMENT; } for(j = (L->length)-1; j >= i-1; j--) L->elem[j+1] = L->elem[j]; L->elem[i-1] = e; ++L->length; return OK;}Status ListDelete_Sq(SqList *L, int i, ElemType *e){ /*删除顺序表L中的第i个(1<=i<=ListLength(L))数据元素,并用e返回其值,L的长度减1*/ int j; if(i < 1 || i > L->length) //判断i值是否合法 return ERROR; *e = L->elem[i-1]; for(j = i; j < L->length; j++) L->elem[j-1] = L->elem[j]; L->length--; return OK;}void Union_Sq(SqList *La, SqList *Lb) //集合的合并操作{ /*将所有在线性表Lb中但不在La中的数据元素依次插入到La中*/ int e; int La_len, Lb_len; int i; La_len = La->length, Lb_len = Lb->length; for(i = 1; i <= Lb_len; i++){ e = Lb->elem[i-1]; if(!LocateElem_Sq(*La,e)) ListInsert_Sq(La, ++La_len, e); }}void MergeList_Sq(SqList La, SqList Lb, SqList *Lc){ /*已知线性表La和Lb中的数据元素按值非递减排列*/ /*归并La和Lb得到新的线性表Lc,Lc的数据元素也按值非递减排列*/ int i = 0, j = 0, k = 1; int ai,bj; InitList_Sq(Lc); while(i <= La.length-1 && j <= Lb.length-1){ ai = La.elem[i]; bj = Lb.elem[j]; if(ai <= bj){ ListInsert_Sq(Lc,k,ai); i++; k++; } else{ ListInsert_Sq(Lc,k,bj); j++; k++; } } while(i <= La.length-1){ ai = La.elem[i]; ListInsert_Sq(Lc, k, ai); i++; k++; } while(j <= Lb.length-1){ bj = Lb.elem[j]; ListInsert_Sq(Lc, k, bj); j++; k++; }}void Print_Sq(SqList L){ int i; for(i = 0; i < L.length; i++) printf("%d ", L.elem[i]); printf("\n");}void Print_Hyphen(int n){ int i; for(i = 0; i < n; i++) printf("-");}
阅读全文
1 0
- 线性表的顺序存储与实现
- 线性表的顺序存储与实现
- 线性表的顺序存储的实现
- 线性表的顺序存储实现
- 数组实现线性表的顺序存储
- java实现线性表的顺序存储
- 线性表的Java实现--顺序存储
- 线性表的顺序存储实现
- 线性表的动态顺序存储实现
- C++实现顺序存储的线性表
- 线性表的动态顺序存储实现
- 线性表的顺序存储实现
- 线性表顺序存储的实现
- 线性表的顺序存储实现
- 线性表的顺序存储实现
- 线性表的顺序存储实现c++
- 线性表的顺序存储实现和链式存储实现
- 线性表---顺序存储实现
- postman 使用
- 批处理--ren重命名
- Spring--IoC_值注入
- Android Studio BuildType 构建类型
- 记录一个cell的Action事件无响应bug
- 线性表的顺序存储与实现
- java的多线程同步剖析
- 【poj3264】 Balanced Lineup(st表)
- adb命令安装apk
- c++ primer
- NKOJ 3844 服务器信息储存(最短路)
- Eclipse安装svn插件的几种方式
- Python词云 wordcloud 十五分钟入门与进阶
- library module 只有release版本的问题