线性表(顺序存储)
线性表
线性结构特点:
有“头”元素有“尾”元素,中间的元素有“前驱”元素和“后继”元素 线性表是一个数据元素的有序(次序)集
(1)集合中必存在唯一的一个“第一元素”;
(2)集合中必存在唯一的一个 “最后元素” ;
(3)除最后元素在外,均有 唯一的后继;
(4)除第一元素之外,均有 唯一的前驱。
抽象数据类型线性表的定义如下:
ADT List {
数据对象: D={ ai | ai ∈ElemSet, i=1,2,...,n, n≥0 } {称 n 为线性表的表长; 称 n=0 时的线性表为空表。}
数据关系: R1={ <ai-1 ,ai >|ai-1 ,ai∈D, i=2,...,n } {设线性表为 (a1,a2, . . . ,ai,. . . ,an), 称 i 为 ai 在线性表中的位序。}
基本操作:
结构初始化操作(添加)
结构销毁操作(删除)
引用型操作(查询)
加工型操作(修改)
}ADT List
结构初始化操作(添加) InitList( &L ) 操作结果:构造一个空的线性表L。
结构销毁操作(删除) DestroyList( &L ) 初始条件:线性表 L 已存在。 操作结果:销毁线性表 L。
引用型操作(查询)
引用型操作(查询) ListEmpty( L ) (线性表判空) 初始条件:线性表L已存在。 操作结果:若L为空表,则返回TRUE, 否则返回FALSE。
引用型操作(查询) ListLength( L ) (求线性表的长度) 初始条件:线性表L已存在。 操作结果:返回L中元素个数。
引用型操作(查询) PriorElem( L, cur_e, &pre_e ) (求数据元素的前驱) 初始条件:线性表L已存在。 操作结果:若cur_e是L的元素,但不是第一,则用pre_e 返回它的前驱,否则操作失败,pre_e无定义。
引用型操作(查询) NextElem( L, cur_e, &next_e ) (求数据元素的后继) 初始条件:线性表L已存在。 操作结果:若cur_e是L的元素,但不是最后一个,则用next_e返回它的后继,否则操作失败,next_e无定义。
引用型操作(查询) GetElem( L, i, &e ) (求线性表中某个数据元素) 初始条件:线性表L已存在。且 1≤i≤ListLength (L)。 操作结果:用 e 返回L中第 i 个元素的值。
引用型操作(查询) LocateElem( L, e, compare( ) ) (定位函数) 初始条件:线性表L已存在,e为给定值, compare( )是元素判定函数。 操作结果:返回L中第1个与e满足关系compare( )的元素的位序。若这样的元素不存在,则返回值为0。
引用型操作(查询) ListTraverse(L, visit( )) (遍历线性表) 初始条件:线性表L已存在,visit() 为某个访问函数。 操作结果:依次对L的每个元素调用函数visit( )。一旦visit( )失败,则操作失败。
加工型操作(修改)
加工型操作(修改) ClearList( &L ) (线性表置空) 初始条件:线性表L已存在。 操作结果:将L重置为空表。
加工型操作(修改) PutElem( &L, i, &e ) (改变数据元素的值) 初始条件:线性表L已存在,且 1≤i≤ListLength (L) 。 操作结果: L中第i个元素赋值同e的值。
加工型操作(修改) ListInsert( &L, i, e ) (插入数据元素) 初始条件:线性表L已存在, 且 1≤i≤ListLength (L)+1 。 操作结果:在L的第i个元素之前插入新的元素e,L的长度增1。
加工型操作(修改) ListDelete(&L, i, &e) (删除数据元素) 初始条件:线性表L已存在且非空, 1≤i≤LengthList(L) 。 操作结果:删除L的第i个元素,并用e返回其值,L的长度减1。
数据结构代码(参考链接http://wenku.baidu.com/link?url=Iyjsczu_DGbiqTZlWDJt8u2BAfGI0XMPDyPI0Tz8ESEbvZRJbk6NlKl5O4g1eRvr-MoS7Kx14Tu4pqhn2Xrn-7KOc1E5xLHNwUQwokPFS6u)
基本操作及算法
1 #include<stdio.h> 2 #include<stdlib.h> 3 /*自定义*/ 4 #define LIST_INIT_SIZE 10 /* 线性表存储空间的初始分配量 */ 5 #define LISTINCREMENT 2 /* 线性表存储空间的分配增量 */ 6 #define INFEASIBLE 999999999/*超出线性表存储空间*/ 7 #define OK 1 8 #define TRUE 1 9 #define FALSE 0 10 #define OVERFLOW 0/*溢出*/ 11 #define ERROR 0/*错误*/ 12 typedef int Status; 13 typedef int ElemType; 14 #define LIST_INIT_SIZE 10 /* 线性表存储空间的初始分配量 */ 15 #define LISTINCREMENT 2 /* 线性表存储空间的分配增量 */ 16 typedef struct 17 { 18 ElemType *elem; /* 存储空间基址 */ 19 int length; /* 当前长度 */ 20 int listsize; /* 当前分配的存储容量(以sizeof(ElemType)为单位) */ 21 }SqList; 22 /*顺序表示的线性表(存储结构)的12个基本操作*/ 23 Status InitList(SqList &L) 24 { 25 /* 操作结果:构造一个空的顺序线性表 */ 26 L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType)); 27 if(!L.elem) 28 exit(OVERFLOW); 29 L.length=0; 30 L.listsize=LIST_INIT_SIZE; 31 return OK; 32 } 33 Status DestroyList(SqList &L) 34 { 35 /* 初始条件:顺序线性表L已存在。操作结果:销毁顺序线性表L */ 36 free(L.elem); 37 L.elem=NULL; 38 L.length=0; 39 L.listsize=0; 40 return OK; 41 } 42 43 Status ClearList(SqList &L) 44 { 45 /* 初始条件:顺序线性表L已存在。操作结果:将L重置为空表 */ 46 L.length=0; 47 return OK; 48 } 49 Status ListEmpty(SqList L) 50 { 51 /* 初始条件:顺序线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */ 52 if(!L.length) 53 return TRUE; 54 else 55 return FALSE; 56 } 57 ElemType ListLength(SqList L) 58 { 59 /* 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数 */ 60 return L.length; 61 } 62 ElemType GetElem(SqList L,int i,ElemType &e) 63 { 64 /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */ 65 /* 操作结果:用e返回L中第i个数据元素的值 */ 66 if(i<1||i>L.length) 67 exit(ERROR); 68 e=L.elem[i-1];//返回第i个数据 69 return OK; 70 } 71 72 Status compare(ElemType c1,ElemType c2) /* 数据元素判定函数(平方关系) */ 73 { 74 if(c1==c2*c2) 75 return TRUE; 76 else 77 return FALSE; 78 } 79 80 int LocateElem(SqList L,ElemType e,Status(*compare)(ElemType,ElemType)) 81 { 82 /* 初始条件:顺序线性表L已存在,compare()是数据元素判定函数(满足为1,否则为0) */ 83 /* 操作结果:返回L中第1个与e满足关系compare()的数据元素的位序。 */ 84 /* 若这样的数据元素不存在,则返回值为0。算法2.6 */ 85 ElemType *p; 86 int i=1; 87 p=L.elem; 88 while(i<=L.length&&!(*compare)(*p++,e)) 89 ++i; 90 if(i<=L.length) 91 return i; 92 else 93 return 0; 94 } 95 Status PriorElem(SqList L,ElemType cur_e,ElemType &pre_e) 96 { 97 /* 初始条件:顺序线性表L已存在 */ 98 /* 操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱, */ 99 /* 否则操作失败,pre_e无定义 */ 100 int i=2; 101 ElemType *p=L.elem+1; 102 while(i<=L.length&&*p!=cur_e) 103 { 104 p++; 105 i++; 106 } 107 if(i>L.length) 108 return INFEASIBLE; 109 else 110 { 111 pre_e=*--p; 112 return OK; 113 } 114 } 115 116 Status NextElem(SqList L,ElemType cur_e,ElemType &next_e) 117 { 118 /* 初始条件:顺序线性表L已存在 */ 119 /* 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继, */ 120 /* 否则操作失败,next_e无定义 */ 121 int i=1; 122 ElemType *p=L.elem; 123 while(i<L.length&&*p!=cur_e) 124 { 125 i++; 126 p++; 127 } 128 if(i==L.length) 129 return INFEASIBLE; 130 else 131 { 132 next_e=*++p; 133 return OK; 134 } 135 } 136 137 Status ListInsert(SqList &L,int i,ElemType e) /* 算法2.4 */ 138 { 139 /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L)+1 */ 140 /* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */ 141 ElemType *newbase,*q,*p; 142 if(i<1||i>L.length+1) /* i值不合法 */ 143 return ERROR; 144 if(L.length>=L.listsize) /* 当前存储空间已满,增加分配 */ 145 { 146 newbase=(ElemType *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType)); 147 if(!newbase) 148 exit(OVERFLOW); /* 存储分配失败 */ 149 L.elem=newbase; /* 新基址 */ 150 L.listsize+=LISTINCREMENT; /* 增加存储容量 */ 151 } 152 q=&(L.elem[i-1]); /* q为插入位置 */ 153 for(p=&(L.elem[i-1]);p>=q;--p) /* 插入位置及之后的元素右移 */ 154 *(p+1)=*p; 155 *q=e; /* 插入e */ 156 ++L.length; /* 表长增1 */ 157 return OK; 158 } 159 160 Status ListDelete(SqList &L,int i,ElemType &e) 161 { 162 /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */ 163 /* 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1 */ 164 ElemType *p,*q; 165 if(i<1||i>L.length) /* i值不合法 */ 166 return ERROR; 167 p=&L.elem[i-1]; /* p为被删除元素的位置 */ 168 e=*p; /* 被删除元素的值赋给e */ 169 q=L.elem+L.length-1; /* 表尾元素的位置 */ 170 for(++p;p<=q;++p) /* 被删除元素之后的元素左移 */ 171 *(p-1)=*p; 172 --L.length; /* 表长减1 */ 173 return OK; 174 } 175 176 void visit(ElemType *c) /* ListTraverse()调用的函数(类型要一致) */ 177 { 178 printf("%d ",*c); 179 } 180 181 void dbl(ElemType *c) /* ListTraverse()调用的另一函数(元素值加倍) */ 182 { 183 *c*=2; 184 } 185 Status ListTraverse(SqList L,void(*visit)(ElemType*)) 186 { 187 /* 初始条件:顺序线性表L已存在 */ 188 /* 操作结果:依次对L的每个数据元素调用函数vi()。一旦vi()失败,则操作失败 */ 189 /* vi()的形参加'&',表明可通过调用vi()改变元素的值 */ 190 ElemType *p; 191 int i; 192 p=L.elem; 193 for(i=1;i<=L.length;i++) 194 visit(p++); 195 printf("\n"); 196 return OK; 197 } 198 Status equal(ElemType c1,ElemType c2) 199 { 200 /* 判断是否相等的函数,Union()用到 */ 201 if(c1==c2) 202 return TRUE; 203 else 204 return FALSE; 205 } 206 207 void Union(SqList &La,SqList Lb) /* 算法2.1 */ 208 { 209 /* 将所有在线性表Lb中但不在La中的数据元素插入到La中 */ 210 ElemType e; 211 int La_len,Lb_len; 212 int i; 213 La_len=ListLength(La); /* 求线性表的长度 */ 214 Lb_len=ListLength(Lb); 215 for(i=1;i<=Lb_len;i++) 216 { 217 GetElem(Lb,i,e); /* 取Lb中第i个数据元素赋给e */ 218 if(!LocateElem(La,e,equal)) /* La中不存在和e相同的元素,则插入之 */ 219 ListInsert(La,++La_len,e); 220 } 221 } 222 223 void MergeList(SqList La,SqList Lb,SqList &Lc) /* 算法2.2 */ 224 { 225 /* 已知线性表La和Lb中的数据元素按值非递减排列。 */ 226 /* 归并La和Lb得到新的线性表Lc,Lc的数据元素也按值非递减排列 */ 227 int i=1,j=1,k=0; 228 int La_len,Lb_len; 229 ElemType ai,bj; 230 InitList(Lc); /* 创建空表Lc */ 231 La_len=ListLength(La); 232 Lb_len=ListLength(Lb); 233 while(i<=La_len&&j<=Lb_len) /* 表La和表Lb均非空 */ 234 { 235 GetElem(La,i,ai); 236 GetElem(Lb,j,bj); 237 if(ai<=bj) 238 { 239 ListInsert(Lc,++k,ai); 240 ++i; 241 } 242 else 243 { 244 ListInsert(Lc,++k,bj); 245 ++j; 246 } 247 } 248 while(i<=La_len) /* 表La非空且表Lb空 */ 249 { 250 GetElem(La,i++,ai); 251 ListInsert(Lc,++k,ai); 252 } 253 while(j<=Lb_len) /* 表Lb非空且表La空 */ 254 { 255 GetElem(Lb,j++,bj); 256 ListInsert(Lc,++k,bj); 257 } 258 } 259 260 void MergeList_Sq(SqList La,SqList Lb,SqList &Lc) /* 算法2.7 */ 261 { 262 /* 已知顺序线性表La和Lb的元素按值非递减排列。 */ 263 /* 归并La和Lb得到新的顺序线性表Lc,Lc的元素也按值非递减排列 */ 264 ElemType *pa,*pa_last,*pb,*pb_last,*pc; 265 pa=La.elem; 266 pb=Lb.elem; 267 Lc.listsize=Lc.length=La.length+Lb.length;/*不用InitList()创建空表Lc */ 268 pc=Lc.elem=(ElemType *)malloc(Lc.listsize*sizeof(ElemType)); 269 if(!Lc.elem) /* 存储分配失败 */ 270 exit(OVERFLOW); 271 pa_last=La.elem+La.length-1; 272 pb_last=Lb.elem+Lb.length-1; 273 while(pa<=pa_last&&pb<=pb_last) /* 表La和表Lb均非空 */ 274 { /* 归并 */ 275 if(*pa<=*pb) 276 *pc++=*pa++; 277 else 278 *pc++=*pb++; 279 } 280 while(pa<=pa_last) /* 表La非空且表Lb空 */ 281 *pc++=*pa++; /* 插入La的剩余元素 */ 282 while(pb<=pb_last) /* 表Lb非空且表La空 */ 283 *pc++=*pb++; /* 插入Lb的剩余元素 */ 284 }
主函数
1 void print(ElemType *c) 2 { 3 printf("%d ",*c); 4 } 5 6 void Sq_Main() 7 { 8 SqList L; 9 ElemType e,e0; 10 Status i; 11 int j,k; 12 i=InitList(L); 13 printf("初始化L后:L.elem=%u L.length=%d L.listsize=%d\n",L.elem,L.length,L.listsize); 14 for(j=1;j<=5;j++) 15 i=ListInsert(L,1,j); 16 printf("在L的表头依次插入1~5后:*L.elem="); 17 for(j=1;j<=5;j++) 18 printf("%d ",*(L.elem+j-1)); 19 printf("\n"); 20 printf("L.elem=%u L.length=%d L.listsize=%d\n",L.elem,L.length,L.listsize); 21 i=ListEmpty(L); 22 printf("L是否空:i=%d(1:是 0:否)\n",i); 23 i=ClearList(L); 24 printf("清空L后:L.elem=%u L.length=%d L.listsize=%d\n",L.elem,L.length,L.listsize); 25 i=ListEmpty(L); 26 printf("L是否空:i=%d(1:是 0:否)\n",i); 27 for(j=1;j<=10;j++) 28 ListInsert(L,j,j); 29 printf("在L的表尾依次插入1~10后:*L.elem="); 30 for(j=1;j<=10;j++) 31 printf("%d ",L.elem[j-1]); 32 printf("\n"); 33 printf("L.elem=%u L.length=%d L.listsize=%d\n",L.elem,L.length,L.listsize); 34 ListInsert(L,1,0); 35 printf("在L的表头插入0后:*L.elem="); 36 for(j=1;j<=ListLength(L);j++) /* ListLength(L)为元素个数 */ 37 printf("%d ",L.elem[j-1]); 38 printf("\n"); 39 printf("L.elem=%u(有可能改变) L.length=%d(改变) L.listsize=%d(改变)\n",L.elem,L.length,L.listsize); 40 GetElem(L,5,e); 41 printf("第5个元素的值为:%d\n",e); 42 for(j=3;j<=4;j++) 43 { 44 k=LocateElem(L,j,compare); 45 if(k) 46 printf("第%d个元素的值为%d的平方\n",k,j); 47 else 48 printf("没有值为%d的平方的元素\n",j); 49 } 50 for(j=1;j<=2;j++) /* 测试头两个数据 */ 51 { 52 GetElem(L,j,e0); /* 把第j个数据赋给e0 */ 53 i=PriorElem(L,e0,e); /* 求e0的前驱 */ 54 if(i==INFEASIBLE) 55 printf("元素%d无前驱\n",e0); 56 else 57 printf("元素%d的前驱为:%d\n",e0,e); 58 } 59 for(j=ListLength(L)-1;j<=ListLength(L);j++) /* 最后两个数据 */ 60 { 61 GetElem(L,j,e0); /* 把第j个数据赋给e0 */ 62 i=NextElem(L,e0,e); /* 求e0的后继 */ 63 if(i==INFEASIBLE) 64 printf("元素%d无后继\n",e0); 65 else 66 printf("元素%d的后继为:%d\n",e0,e); 67 } 68 k=ListLength(L); /* k为表长 */ 69 for(j=k+1;j>=k;j--) 70 { 71 i=ListDelete(L,j,e); /* 删除第j个数据 */ 72 if(i==ERROR) 73 printf("删除第%d个数据失败\n",j); 74 else 75 printf("删除的元素值为:%d\n",e); 76 } 77 printf("依次输出L的元素:"); 78 ListTraverse(L,visit); /* 依次对元素调用visit(),输出元素的值 */ 79 printf("L的元素值加倍后:"); 80 ListTraverse(L,dbl); /* 依次对元素调用dbl(),元素值乘2 */ 81 ListTraverse(L,visit); 82 DestroyList(L); 83 printf("销毁L后:L.elem=%u L.length=%d L.listsize=%d\n",L.elem,L.length,L.listsize); 84 } 85 86 void Union_Main() 87 { 88 SqList La,Lb; 89 Status i; 90 int j; 91 i=InitList(La); 92 if(i==1) /* 创建空表La成功 */ 93 for(j=1;j<=5;j++) /* 在表La中插入5个元素 */ 94 i=ListInsert(La,j,j); 95 printf("La= "); /* 输出表La的内容 */ 96 ListTraverse(La,print); 97 InitList(Lb); /* 也可不判断是否创建成功 */ 98 for(j=1;j<=5;j++) /* 在表Lb中插入5个元素 */ 99 i=ListInsert(Lb,j,2*j); 100 printf("Lb= "); /* 输出表Lb的内容 */ 101 ListTraverse(Lb,print); 102 Union(La,Lb); 103 printf("new La= "); /* 输出新表La的内容 */ 104 ListTraverse(La,print); 105 } 106 void MergeList_Main() 107 { 108 SqList La,Lb,Lc; 109 int j,a[4]={3,5,8,11},b[7]={2,6,8,9,11,15,20}; 110 InitList(La); /* 创建空表La */ 111 for(j=1;j<=4;j++) /* 在表La中插入4个元素 */ 112 ListInsert(La,j,a[j-1]); 113 printf("La= "); /* 输出表La的内容 */ 114 ListTraverse(La,print); 115 InitList(Lb); /* 创建空表Lb */ 116 for(j=1;j<=7;j++) /* 在表Lb中插入7个元素 */ 117 ListInsert(Lb,j,b[j-1]); 118 printf("Lb= "); /* 输出表Lb的内容 */ 119 ListTraverse(Lb,print); 120 MergeList(La,Lb,Lc); 121 printf("Lc= "); /* 输出表Lc的内容 */ 122 ListTraverse(Lc,print); 123 } 124 125 void MergeList_Sq_Main() 126 { 127 SqList La,Lb,Lc; 128 int j; 129 InitList(La); /* 创建空表La */ 130 for(j=1;j<=5;j++) /* 在表La中插入5个元素 */ 131 ListInsert(La,j,j); 132 printf("La= "); /* 输出表La的内容 */ 133 ListTraverse(La,print); 134 InitList(Lb); /* 创建空表Lb */ 135 for(j=1;j<=5;j++) /* 在表Lb中插入5个元素 */ 136 ListInsert(Lb,j,2*j); 137 printf("Lb= "); /* 输出表Lb的内容 */ 138 ListTraverse(Lb,print); 139 MergeList(La,Lb,Lc); 140 printf("Lc= "); /* 输出表Lc的内容 */ 141 ListTraverse(Lc,print); 142 } 143 144 int main() 145 { 146 printf("--------------------------------------------------------------\n"); 147 Sq_Main(); 148 printf("--------------------------------------------------------------\n"); 149 Union_Main(); 150 printf("--------------------------------------------------------------\n"); 151 MergeList_Main(); 152 printf("--------------------------------------------------------------\n"); 153 MergeList_Sq_Main(); 154 return 0; 155 }

浙公网安备 33010602011771号