顺序表 - 数据结构
顺序表:用一组地址连续的存储单元依次存储线性表的数据元素。
假设线性表的每个元素需占用d个存储单元,并以所占的第一个单元的存储地址作为数据元素的存储位置。
特点:
1)只要确定了存储顺序表的起始位置,顺序表中任一数据元素都可随机存取。
2)为表中相邻的元素赋以相邻的存储位置。
缺点:在作插入或删除操作时,需移动大量元素。
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #define ERROR 0 5 #define OK 1 6 #define OVERFLOW -1 7 #define LIST_INIT_SIZE 100 //顺序表存储空间的初始分配量 8 #define LISTINCREMENT 10 //顺序表存储空间的分配增量 9 typedef int ElemType; 10 typedef int Status; 11 typedef struct { 12 ElemType *elem; //存储空间基址 13 int length; //当前长度 14 int listsize; //当前分配的存储容量 15 } SqList; 16 17 Status InitList_Sq(SqList &L) { 18 // 构造一个空的顺序表L 19 L.elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType)); 20 if (! L.elem) exit(OVERFLOW); 21 L.length = 0; 22 L.listsize = LIST_INIT_SIZE; 23 return OK; 24 } // InitList_Sq 25 26 // 当在顺序表中某个位置插入或删除一个元素时,时间主要耗费在移动元素上 27 Status ListInsert_Sq(SqList &L, int i, ElemType e) { 28 // 在顺序表L中第i个位置之前插入新的元素e 29 // i的合法值为 1<= i <= ListLength_Sq(L)+1 30 if (i < 1 || i > L.length + 1) return ERROR; // i值不合法 31 if (L.length >= L.listsize) { // 当前存储空间已满,增加分配 32 ElemType *newbase = (ElemType *)realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof(ElemType)); 33 if (! newbase) exit(OVERFLOW); // 存储分配失败 34 L.elem = newbase; // 新基址 35 L.listsize += LISTINCREMENT; // 增加存储容量 36 } 37 ElemType *q = &(L.elem[i-1]); 38 for (ElemType *p = &(L.elem[L.length-1]); p >= q; --p) //插入位置及之后元素右移 39 *(p+1) = *p; 40 *q = e; // 插入e 41 ++L.length; // 表长增1 42 return OK; 43 } // ListInsert_Sq,时间复杂度为O(n) 44 45 Status ListDelete_Sq(SqList &L, int i, ElemType &e) { 46 // 在顺序表L中删除第i个元素,并用e返回其值 47 // i的合法值为 i<= i <= ListLength_Sq(L) 48 if (i < 1 || i > L.length) return ERROR; // i值不合法 49 ElemType *p = &(L.elem[i-1]); // p为被删除元素的位置 50 e = *p; 51 ElemType *q = &(L.elem[L.length-1]); //表尾元素位置 52 for (++p; p <= q; ++p) //被删除元素之后的元素左移 53 *(p-1) = *p; 54 --L.length; // 表长减1 55 return OK; 56 } // ListDelete_Sq,时间复杂度为O(n) 57 58 int LocateElem_Sq(SqList &L, ElemType e) { 59 // 在顺序表中查找第一个值与e相等的元素的位序 60 // 若找到,则返回其在L中的位序,否则返回0 61 int i = 1; // i的初值为第1个元素的位徐 62 ElemType *p = L.elem; //第1个元素的存储位置 63 while (i <= L.length && (*(p+i-1) != e)) 64 ++i; 65 if (i <= L.length) return i; 66 else return 0; 67 } // LocateElem_Sq,时间复杂度为O(n) 68 69 void Union(SqList &La, SqList &Lb) { 70 // 将所有在顺序表Lb中但不在La中的数据元素插入到La中 71 int La_len = La.length; //求顺序表的长度 72 int Lb_len = Lb.length; 73 for (int i = 1; i <= Lb_len; ++i) { 74 ElemType e = Lb.elem[i-1]; // 取Lb中第i个数据元素赋给e 75 // La中不存在和e相同的元素,则插入La 76 if (!LocateElem_Sq(La, e)) ListInsert_Sq(La, ++La_len, e); 77 } 78 } // Union 79 80 void MergeList_Sq(SqList &La, SqList &Lb, SqList &Lc) { 81 // 归并La和Lb得到新的顺序表Lc 82 ElemType *pa = La.elem; 83 ElemType *pb = Lb.elem; 84 Lc.listsize = Lc.length = La.length + Lb.length; 85 ElemType *pc = Lc.elem = (ElemType *)malloc(Lc.listsize * sizeof(ElemType)); 86 if (!Lc.elem) exit(OVERFLOW); 87 ElemType *pa_last = La.elem + La.length - 1; 88 ElemType *pb_last = Lb.elem + Lb.length - 1; 89 while (pa <= pa_last && pb <= pb_last) { // 归并 90 if (*pa <= *pb) *pc++ = *pa++; 91 else *pc++ = *pb++; 92 } 93 while (pa <= pa_last) *pc++ = *pa++; // 插入La的剩余元素 94 while (pb <= pb_last) *pc++ = *pb++; // 插入Lb的剩余元素 95 } // MergeList_Sq 96 97 Status Print_Sq(SqList &L) { 98 for (int i = 0; i < L.length; ++i) { 99 printf("%d ", L.elem[i]); 100 } 101 putchar('\n'); 102 return OK; 103 } 104 105 int main () { 106 SqList La; 107 InitList_Sq(La); 108 ListInsert_Sq(La, 1, 3); 109 ListInsert_Sq(La, 2, 5); 110 ListInsert_Sq(La, 3, 7); 111 ListInsert_Sq(La, 4, 8); 112 ListInsert_Sq(La, 5, 11); 113 printf("La is: "); 114 Print_Sq(La); 115 116 SqList Lb; 117 InitList_Sq(Lb); 118 ListInsert_Sq(Lb, 1, 2); 119 ListInsert_Sq(Lb, 2, 3); 120 ListInsert_Sq(Lb, 3, 5); 121 ListInsert_Sq(Lb, 4, 6); 122 ListInsert_Sq(Lb, 5, 8); 123 ListInsert_Sq(Lb, 6, 8); 124 ListInsert_Sq(Lb, 7, 9); 125 ListInsert_Sq(Lb, 8, 11); 126 ListInsert_Sq(Lb, 9, 11); 127 ListInsert_Sq(Lb, 10, 15); 128 ListInsert_Sq(Lb, 11, 20); 129 printf("Lb is: "); 130 Print_Sq(Lb); 131 132 ElemType e; 133 ListDelete_Sq(La, 3, e); 134 printf("New La: "); 135 Print_Sq(La); 136 printf("The deleted element is: %d\n", e); 137 138 int index = LocateElem_Sq(La, 8); 139 printf("find the same element in La's position is %d\n", index); 140 141 Union(La, Lb); 142 printf("Unioned La is: "); 143 Print_Sq(La); 144 145 SqList Lc; 146 // InitList_Sq(Lc); 147 MergeList_Sq(La, Lb, Lc); 148 printf("Merge La and Lb, getting Lc: "); 149 Print_Sq(Lc); 150 return 0; 151 }
输出为:
La is: 3 5 7 8 11 Lb is: 2 3 5 6 8 8 9 11 11 15 20 New La: 3 5 8 11 The deleted element is: 7 find the same element in La's position is 3 Unioned La is: 3 5 8 11 2 6 9 15 20 Merge La and Lb, getting Lc: 2 3 3 5 5 6 8 8 8 9 11 2 6 9 11 11 15 15 20 20