顺序存储结构封装需要三个属性:
1.存储空间的起始位置,数组data,它的存储位置就是线性表存储空间的存储位置
2.线性表的最大存储容量,数组的长度MaxSize
3.线性表的当前长度:length
当前长度与数组长度区别:数组长度就是该顺序表的总长度,如果不进行扩容的话,就是不变的。而当前长度在数据的变化中,就会发生相应的变化。
PS:线性表是正常的读数方法,一下标1开始的。
存储时间性能:O(1)
性能:存取以及读取不管是在哪个位置,其时间复杂度都是O(1),而在插入还是删除其时间复杂度都是O(n)
结论:比较适合数据的存取而不适合经常性增删的情况。
顺序存储结构的优缺点
1.优点:
- 无须为表示表中元素之间的逻辑关系而增加额外的存储空间
- 可以快速的存取表中任意位置的元素。
2.缺点:
- 插入以及删除操作需要移动大量的元素。
- 当线性表长度变化较大时,难以确定存储空间的容量。
- 容易造成存储空间的碎片。
具体代码的实现:
// 头文件部分,进行常量参数初始化 #define LIST_INT_SIZE 10 //线性顺序表初始动态分配内存大小 #define INCREAMENT 2 //线性表扩容一次性增量 #define OK 1 #define ERROW -1 #define OVERFLOW -2 #include<stdio.h> #include <stdlib.h>//malloc函数包含在其中 typedef int Elemtype; //线性表的数据类型 typedef int Status; // 状态数据类型 // 顺序表存储结构定义 typedef struct { Elemtype *elem; //定义线性表内数据元素的数据类型 int length; //表当前长度 int listsize; //表当前空间容量大小 } SqList; //表名 // 初始化一个顺序表 Status InitList(SqList &L) { L.elem = (Elemtype *)malloc(LIST_INT_SIZE * sizeof(Elemtype)) ;//动态分配内存,分配后可以将l.elem作为数组使用 if(!L.elem) { //对内存分配的结果判断 exit(OVERFLOW); } //这个地方可以去查一下资料 // if(L.elem == NULL) { // printf("分配内存失败") // exit(1); // } //关于内存分配结果的判断,又该如何去进行判断 //这种方法进行判断又是否正确 L.length = 0; //对表长初始化归0 L.listsize = LIST_INT_SIZE; return OK; } // 创建一个顺序表 Status CreateList(SqList &L) { int i; InitList(L); printf("请输入元素个数:\n"); scanf("%d",&L.length); printf("\n请输入您要输入的元素\n"); for(i=0; i<L.length; i++) { scanf("%d",&L.elem[i]); } printf("顺序表已创建成功,打印表请选择功能 *3\n"); return OK; } // 顺序表的遍历 Status TraverseList(SqList &L) { int i; printf("表中元素为:\n"); for(i=0; i<L.length; i++) printf("%d ",L.elem[i]); printf("\n\n顺序表输出完毕!\n"); } //顺序表的插入 // 表L 位置 i Elemtype 要插入的元素 Status InsertList(SqList &L,int i,Elemtype e) { int* newbase; int j; if(i < 1 ||i > L.length+1) { // 判断所要插入的位置 return ERROW; } if(L.length>=L.listsize) { newbase = (Elemtype*)realloc(L.elem,(L.listsize+INCREAMENT)*sizeof(Elemtype)); if(!newbase) { exit(OVERFLOW); } L.elem = newbase; L.listsize += INCREAMENT; } 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 deleteListElem(SqList &L,int i) { Elemtype e; int j; if(i<1 || i>L.length) { return ERROW; } e = L.elem[i-1]; for(j = i-1 ; j<=L.length; j++) { L.elem[j] = L.elem[j+1]; } L.length--; return e; } //判断一个值是不是线性表中的元素并返回第几个元素 Status ifElemExit(SqList &L,Elemtype e) { int i = 0; for(; i<L.length; i++) { if(e==L.elem[i]) break; } if(i>=L.length) { return ERROW; } else { return i; } } //输出一个位置的数据元素 Status GetElem(SqList &L,int i) { if(i<1||i>L.length) { return ERROW; } return L.elem[i-1]; } //根据元素的值来进行删除 Status deleteElemByR(SqList &L,Elemtype e) { int i = 0; i = ifElemExit(L,e); if(i==-1) { printf("该值不再线性表中:"); return ERROW; } else { deleteListElem(L,i+1); printf("删除成功!删除的是位置为%d,值为%d",i,e); return OK; } } //将线性表进行递减排序操作 Status SortByMao(SqList &L) { Elemtype e; for(int j=0; j<L.length; j++) { for(int i=0; i<L.length-i-j; i++) { if(L.elem[i]<L.elem[i+1]) { e = L.elem[i]; L.elem[i] = L.elem[i+1]; L.elem[i+1]=e; } } } } void UnionTwo(SqList &la,SqList &lb) { int la_length = la.length; int lb_length = lb.length; for(int i=1;i<=lb.length;i++){ Elemtype e= GetElem(Lb,i); if(ifElemExit(La,e)==-1){ InsertList(La,la_length,e); la_length++; la.length++; } } } /***主提示输出函数***/ void printlin() { printf("\n"); printf("\t\t\t线性顺序表基本操作学习系统\n"); printf("\t\t\t ***主菜单***\n\n"); printf("\t\t\t *1 创建一个顺序表\n"); printf("\t\t\t *2 定位输出一个数据元素\n"); printf("\t\t\t *3 输出顺序表中所有元素\n"); printf("\t\t\t *4 定位插入一个数据元素\n"); printf("\t\t\t *5 定位删除一个数据元素\n"); printf("\t\t\t *6 定值删除一个数据元素\n"); printf("\t\t\t *7 清空顺序表\n"); printf("\t\t\t *8 销毁顺序表\n"); printf("\t\t\t *9 对表内数据元素进行非递减排序\n"); printf("\t\t\t *0 结束程序\n"); } //清空线性表 void clearList(SqList &L) { if(L.length!=0) { L.length = 0; //由于顺序表的用得是与数组一样的内存空间, //所以标的清空只要将表长归零即可,由此可见,表长是线性表非常重要的部分 } } //销毁线性表 void destoryList(SqList &L) { if(L.length!=0) { free(L.elem); L.elem = NULL;//使用free后就需要对元素进行赋空操作 } } int main() { int i,j,k; Elemtype e; SqList L; L.length=0; printf("编写此程序目的是自我学习线性表顺序表\n"); printlin(); while(1) { int t; scanf("%d",&t); if(t!=0) if(t==1||L.length!=0) { switch(t) { case 1: if(L.length!=0) { printf("顺序表已存在,是否重新创建顺序表?\n"); printf("*1 是 *2 否\n"); scanf("%d",&i); if(i==1) CreateList(L); } else CreateList(L); break; case 0: break; case 3: TraverseList(L); break; case 7: clearList(L); printf("清空完毕,返回主菜单\n\n"); break; case 4: printf("输入要插入的位置\n"); scanf("%d",&i); printf("请输入要插入的数据\n"); scanf("%d",&j); k=InsertList(L,i,j); if(k==-1) { printf("插入位置不合法,插入数据操作失败!\n\n"); } else printf("插入数据成功\n\n"); break; case 5: printf("请输入要删除数据位置\n"); scanf("%d",&i); e = deleteListElem(L,i); printf("删除掉的元素是第%d个位置,它的值是%d",i,e); break; case 2: printf("请输入要需要得到数据位置:"); scanf("%d",&i); e = GetElem(L,i); printf("第%d个位置上的元素值为:%d",i,e); break; case 6: printf("请输入需要删除的值:"); scanf("%d",&e); deleteElemByR(L,e); break; case 8: destoryList(L); printf("销毁成功!"); break; case 9: SortByMao(L); break; default: { printf("输入有误,可以重新选择,退出按0!\n"); } } } else printf("顺序表未创建或已清空或销毁,请先创建顺序表\n"); system("pause"); system("CLS"); printlin(); if(t==0) break; } return 0; }
来源:https://www.cnblogs.com/strator/p/7216172.html