线性表的动态内存分配顺序存储结构
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性表的动态内存分配顺序存储结构相关的知识,希望对你有一定的参考价值。
1.线性表是最简单的一种数据结构,很容易实现其中单个元素的存取操作,但是对于插入和删除操作需要大量的移动。比较适用于相对稳定的线性表。
2.数据元素
struct SqList { ElemType * elem ; //存储空间基址 int length ; //当前长度 int listsize ; //当前分配的存储容量 };
3.创建一个空的线性表
void InitList(SqList &L) { //构造一个空的顺序线性表L L.elem = (ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType)); if(NULL==L.elem) exit(OVERFLOW); //分配失败 L.length = 0; //暂时只有0个内容 L.listsize = LIST_INIT_SIZE; }
4.销毁一个线性表
void DestroyList(SqList &L) { //销毁顺序表L free(L.elem); L.elem = NULL; L.length = 0; L.listsize = 0; }
5.清空一个线性表
void ClearList(SqList &L) { L.length = 0; //有效内容为0个 }
6.判断表是否为空
Status ListEmpty(SqList L) { //空表? if(L.length==0) return TRUE; else return FALSE; }
7.求表的有效元素数据个数
int ListLength(SqList L) { return L.length; }
8.取得表中的某个元素
Status GetElem(SqList L, int i, ElemType &e) { if(i<1||i>L.length) return ERROR; e = *(L.elem + i - 1); return OK; }
9.查找特定的元素
int LocateElem(SqList L,ElemType e, Status (*compare)(ElemType,ElemType)) { //返回L中第一个与元素e满足compare()的数据元素的位序 //Status (*compare)(ElemType,ElemType) 这里定义的一个函数指针,使用它来作为参数,称为回调 //compare 是一个函数指针 int i = 1; ElemType *p = L.elem ; while(i<=L.length && !compare(*p++,e)) i++ ; if(i<=L.length) return i ; else return 0; }
10.获取某个元素的前驱后继
Status PriorElem(SqList L, ElemType cur_e, ElemType &pre_e) { //返回cur_e 的前驱,用pre_e int i = 2; ElemType* p = L.elem+1; //指向第2个 while(i<=L.length && *p != cur_e) { p++; i++; } if(i>L.length) return ERROR; else { pre_e = *(--p); return OK; } } Status NextElem(SqList L,ElemType cur_e,ElemType &next_e) { int i=1; ElemType* p = L.elem; while(i<=L.length && *p !=cur_e) { p++; i++; } if(i>L.length) return ERROR; else { next_e = *(++p); return OK ; } }
11. 向表中插入一个元素
Status ListInsert(SqList &L, int i, ElemType e) { ElemType * newbase,*p,*q; if(i<1||i>L.length+1) return ERROR; if(L.length == L.listsize) //分配的空间都有数据 { newbase = (ElemType*)realloc(L.elem, (L.listsize+LIST_INCREMENT)*sizeof(ElemType)); if(!newbase) exit(OVERFLOW); L.elem = newbase; L.listsize += LIST_INCREMENT; } q = L.elem + i-1; for(p = L.elem+L.length-1; p>=q; p--) //从后往前挪 { *(p+1) = *p ; } *q = e; ++L.length; return OK; }
12.删除一个元素
Status ListDelete(SqList &L,int i, ElemType &e) { ElemType *p, *q; if(i<1||i>L.length) return ERROR; p = L.elem +i-1; e = *p; q = L.elem +L.length -1; for(++p;p<=q;++p) { *(p-1)=*p; } L.length--; return OK ; }
13.遍历表中的元素
void ListTraverse(SqList L,void (*visit)(ElemType &)) { ElemType *p = L.elem; int i; for(i=1; i<=L.length; i++) { visit(*p++); printf("\\n"); } }
最终的测试代码
//线性表的动态分配顺序存储结构 //内存分配 malloc() #include<malloc.h> //malloc() #include<stdlib.h> //atoi(),exit() #include<math.h> //OVERFLOW==3 #include<stdio.h> typedef int Status; typedef int Boolean; #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 typedef int ElemType ; //以整型为例 #define LIST_INIT_SIZE 10 //线性表存储空间的初始分配量 #define LIST_INCREMENT 2 //分配增量 struct SqList { ElemType * elem ; //存储空间基址 int length ; //当前长度 int listsize ; //当前分配的存储容量 }; void InitList(SqList &L) { //构造一个空的顺序线性表L L.elem = (ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType)); if(NULL==L.elem) exit(OVERFLOW); //分配失败 L.length = 0; //暂时只有0个内容 L.listsize = LIST_INIT_SIZE; } void DestroyList(SqList &L) { //销毁顺序表L free(L.elem); L.elem = NULL; L.length = 0; L.listsize = 0; } void ClearList(SqList &L) { L.length = 0; //有效内容为0个 } Status ListEmpty(SqList L) { //空表? if(L.length==0) return TRUE; else return FALSE; } int ListLength(SqList L) { return L.length; } Status GetElem(SqList L, int i, ElemType &e) { if(i<1||i>L.length) return ERROR; e = *(L.elem + i - 1); return OK; } int LocateElem(SqList L,ElemType e, Status (*compare)(ElemType,ElemType)) { //返回L中第一个与元素e满足compare()的数据元素的位序 //Status (*compare)(ElemType,ElemType) 这里定义的一个函数指针,使用它来作为参数,称为回调 //compare 是一个函数指针 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 的前驱,用pre_e int i = 2; ElemType* p = L.elem+1; //指向第2个 while(i<=L.length && *p != cur_e) { p++; i++; } if(i>L.length) return ERROR; else { pre_e = *(--p); return OK; } } Status NextElem(SqList L,ElemType cur_e,ElemType &next_e) { int i=1; ElemType* p = L.elem; while(i<=L.length && *p !=cur_e) { p++; i++; } if(i>L.length) return ERROR; else { next_e = *(++p); return OK ; } } Status ListInsert(SqList &L, int i, ElemType e) { ElemType * newbase,*p,*q; if(i<1||i>L.length+1) return ERROR; if(L.length == L.listsize) //分配的空间都有数据 { newbase = (ElemType*)realloc(L.elem, (L.listsize+LIST_INCREMENT)*sizeof(ElemType)); if(!newbase) exit(OVERFLOW); L.elem = newbase; L.listsize += LIST_INCREMENT; } q = L.elem + i-1; for(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) { ElemType *p, *q; if(i<1||i>L.length) return ERROR; p = L.elem +i-1; e = *p; q = L.elem +L.length -1; for(++p;p<=q;++p) { *(p-1)=*p; } L.length--; return OK ; } void ListTraverse(SqList L,void (*visit)(ElemType &)) { ElemType *p = L.elem; int i; for(i=1; i<=L.length; i++) { visit(*p++); printf("\\n"); } } Status equal(ElemType a,ElemType b) { if(a==b) return TRUE; else return FALSE; } int comp(ElemType a,ElemType b) { if(a==b) return 0; else return (a-b)/abs(a-b); } void printdec(ElemType dec) { printf("%d",dec); } void printref(ElemType &ref) { printf("%d",ref); } void printchar(ElemType ch) { printf("%c",ch); } Status sq(ElemType a,ElemType b) { //判定平方关系 if(a==b*b) return TRUE; else return FALSE; } void Double(ElemType &c) { c *= 2; } int main(void) { SqList L; ElemType e,e0; Status i; int j,k; InitList(L); printf("初始化后,L.length = %d,L.listsize = %d,L.elem = %#x\\n",L.length,L.listsize,L.elem); for(j=1;j<=5;j++) i = ListInsert(L,1,j); printf("在L的表头一次插入1,2,3,4,5,后,*L.elem = "); for(j=1;j<=L.length;j++) printf("%d ",*(L.elem+j-1)); printf("\\n"); ListTraverse(L,printref); i = ListEmpty(L); //是否为空? printf("L.length = %d,L.listsize = %d",L.length,L.listsize); printf("L.elem = %u,L是否为空? i = %d\\n",L.elem,i); ClearList(L); i = ListEmpty(L); //是否为空? printf("L.length = %d,L.listsize = %d",L.length,L.listsize); printf("L.elem = %u,L是否为空? i = %d\\n",L.elem,i); for(j=1;j<=10;j++) i = ListInsert(L,j,j); //在表尾插入 printf("在L的表尾一次插入1--10,后,*L.elem = "); for(j=1;j<=L.length;j++) printf("%d ",*(L.elem+j-1)); printf("\\n"); ListTraverse(L,printref); ListInsert(L,1,0); ListTraverse(L,printref); GetElem(L,5,e); printf("第5个元素为:%d\\n",e); for(j=10;j<=11;j++) { k = LocateElem(L,j,equal); if(k) printf("第%d个元素的值为%d,",k,j); else printf("没有元素的值为%d\\n",j); } for(j=3;j<=4;j++) { k = LocateElem(L,j,sq); if(k) printf("第%d个元素的值的平方为%d,",k,j*j); else printf("没有元素的值的平方为%d\\n",j*j); } for(j=1;j<=2;j++) { GetElem(L,j,e); i = PriorElem(L,e,e0); if(i==ERROR) printf("元素%d没有前驱,",e); else printf("元素%d的前驱为%d",e,e0); } k = ListLength(L); for(j=k+1;j>=k;j--) { i = ListDelete(L,j,e); if(i==ERROR) printf("删除第%d个元素失败!",j); else printf("删除第%d个元素成功,其值为%d",j,e); } ListTraverse(L,Double); printf("L的元素加倍之后,L = "); ListTraverse(L,printref); DestroyList(L); printf("销毁L后,L.length = %d, L.listsize = %d, L.elem = %u \\n",L.length,L.listsize,L.elem); printf("sizeof(L)=%d",sizeof(L)); return 0; } void MergeList(SqList La,SqList Lb,SqList &Lc) { ElemType *pa,*pa_last; ElemType *pb,*pb_last; ElemType *pc; pa = La.elem; pb = Lb.elem; Lc.listsize = Lc.length = La.length+Lb.length; pc = Lc.elem =(ElemType*)malloc(Lc.listsize*sizeof(ElemType)); if(NULL==pc) exit(OVERFLOW); pa_last = La.elem + La.length-1; pb_last = Lb.elem + Lb.length-1; while(pa<=pa_last&&pb<=pb_last) { if(*pa<=*pb) *pc++ = *pa++; else *pc++ = *pb++; } while(pa<=pa_last) *pc++ = *pa++; while(pb<=pb_last) *pc++ = *pb++; } /* int main(void) { SqList La,Lb,Lc; int j; InitList(La); for(j=1;j<=5;j++) //5个元素 ListInsert(La,j,j); //表尾插入 //printf("La.length = %d,La.listsize = %d\\n",La.length,La.listsize); printf("La = \\n"); ListTraverse(La,printref); InitList(Lb); for(j=1;j<=5;j++) //5个元素 ListInsert(Lb,j,j); //表尾插入 ListTraverse(Lb,Double); //printf("Lb.length = %d,Lb.listsize = %d\\n",Lb.length,Lb.listsize); printf("Lb = \\n"); ListTraverse(Lb,printref); MergeList(La,Lb,Lc); printf("Lc = \\n"); ListTraverse(Lc,printref); return 0; } */
以上是关于线性表的动态内存分配顺序存储结构的主要内容,如果未能解决你的问题,请参考以下文章