线性表是最常用且最简单的一种数据结构。简言之,一个线性表是n个数据元素的有限序列。
线性结构的特点是:在数据元素的非空有限集中,
(1)存在唯一的一个被称作“第一个”的数据元素;
(2)存在唯一的一个被称作“最后一个”的数据元素。
(3)除第一个之外,集合中的每个数据元素均只有一个前驱;
(4)除最后一个外,集合中每个数据元素均只有一个后继。
线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素。一般来说,线性表的第i个数据元素ai的存储位置为:
LOC(ai) = LOC(a1)+(i-1)× l;
l表示的是一个数据元素所需的存储量。LOC(a1)为基地址。
线性顺序表的基本操作:
1 //------ 线性表的动态分配顺序存储结构 ------ 2 #define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量 3 #define LISTINCREMENT 10 //线性表存储空间的分配增量 4 typedef struct{ 5 ElemType *elem; //存储空间基址 6 int length; //当前长度 7 int listsize; //当前分配的存储容量(以sizeof(ElemType)为单位) 8 }Sqlist; 9 10 //------ 线性表的初始化 ------ 11 Status InitList_Sq(Sqlist &L){ 12 //构造一个空的线性表L 13 L.elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType)); 14 if(!L.elem) exit(OVERLFLOW); //存储分配失败 15 L.length = 0; //空表长度为0 16 L.listsize = LIST_INIT_SIZE; //初始存储容量 17 return OK; 18 } //InitList_Sq 19 20 //------ 线性表的插入 ------ 21 Status ListInsert_Sq(Sqlist &L,int i,ElemType e){ 22 //在顺序线性表L中第i个位置之前插入新的元素e 23 //i的合法值为1<=i<=ListLength_Sq(L) + 1 24 if(i < 1 || i > L.length+1) return ERROR; //i值不合法 25 if(L.length >= L.listsize){ //当前存储空间已满,增加分配 26 newbase = (ElemType *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType)); 27 if(!newbase) exit(OVERFLOW); //存储分配失败 28 L.elem = newbase; //新基址 29 L.listsize += LISTINCREMENT; //增加存储容量 30 } 31 32 q = &(L.elem[i-1]); //q为插入位置 33 for(p = &(L.elem[L.length-1]); p>=q;--p) 34 *(p+1) = *p; //插入位置及之后的元素右移 35 *q = e; //插入e 36 ++L.length; //表长增1 37 return OK; 38 }//ListInsert_Sq 39 40 41 //------ 线性表的删除 ------ 42 Status ListDelete_Sq(Sqlist &L,int i,ElemType &e){ 43 //在顺序线性表L中删除第i个元素,并用e返回其值 44 //i的合法值为1<=i<=ListLength_Sq(L) 45 if((i < 1) || i > L.length) return ERROR; //i值不合法 46 p = &(L.elem[i-1]); //p为被删除元素的位置 47 e = *p; //被删除元素的值赋给e 48 q = L.elem + L.length - 1; //表尾元素的位置 此句 = &(L.elem[L.length-1]) 49 for(++p;p<=q;++p) *(p-1) = *p; //被删除元素之后的元素左移 50 --L.length; //表长减1 51 return OK; 52 }//ListDelete_Sq 53 54 //------ 线性表的比较查找------ 55 int LocateElem_Sq(Sqlist L,ElemType e,Status(*compare)(ElemType,ElemType)) { 56 //在顺序线性表L中查找第1个值满足compare()的元素的位序 57 //若找到,则返回其在L中的位序,否则返回0 58 i = 1; //i的初值为第1个元素的位序 59 p = L.elem; //p的初值为第1个元素的存储位置 60 while( i <= L.length && !(*compare)(*p++,e)) ++i; 61 if(i <= L.length) return i; 62 else return 0; 63 }//LocateElem_Sq 64 65 //------ 线性表的合并------ 66 void MergeList_Sq(Sqlist La,Sqlist Lb,Sqlist &Lc){ 67 //已知顺序线性表La和Lb的元素按值非递减有序排列 68 //归并La和Lb得到新的顺序线性表Lc,Lc的元素也按值非递减排列有序 69 pa = La.elem; pb = Lb.elem; 70 Lc.listsize = Lc.length = La.length + Lb.length; 71 pc = Lc.elem = (ElemType *)malloc(Lc.listsize * sizeof(ElemType)); 72 if(!Lc.elem) exit(OVERFLOW); //存储分配失败 73 pa_last = La.elem + La.length-1; 74 pb_last = Lb.elem + Lb.length-1; 75 while(pa <= pa_last && pb <=pb_last){ //归并 76 if(*pa <= *pb) *pc++ = *pa++; 77 else *pc++ = *pb++; 78 } 79 while(pa <= pa_last) *pc++ = *pa++; //插入La的剩余元素 80 while(pb <= pb_last) *pc++ = *pb++; //插入Lb的剩余元素 81 } //MergeList_Sq