线性表的顺序实现
线性表(linear_list):
n个数据元素的有限序列
每个数据元素由若干数据项(item)组成,常将数据元素称为记录(record),含有大量记录
的线性表又称为文件。
线性表的顺序实现:
用一组地址连续的存储单元依次存储线性表的数据元素。
再用C语言实现时,需要在线性表初始化时分配一定大小的初始存储空间,但随着初始空间
被占用,需要考虑每次线性表空间增量的问题,下面实现仅仅是简单的选择一个空间增量,
在线性表满时重新分配空间。
顺序表的优缺点:
可以随机取表中任一元素,它的存储位置可用简单直观的公式表示:base + (pos-1) * sizeof(ElemType)
在插入与删除时需移动大量元素
顺序表的实现及相关操作:
(也可以直接在作者GitHub上查看,可能会看着舒服)
1 // 线性表的顺序实现 2 3 #define ElemType int // ElemType作为线性表以及之后其他容器内存储的元素的数据类型,本实现中使用int 4 5 // 线性表的顺序实现 6 #define LIST_INIT_SIZE 100 // 线性表存储空间的初始分配量 7 #define LISTINCREMENT 10 // 线性表存储空间的分配增量 8 typedef struct { 9 ElemType *elem; // 存储空间基址 10 int length; // 线性表当前所用长度 11 int listsize; // 当前分配的存储容量为 listsize * sizeof(ElemType) 12 }SqList; 13 14 // 相关操作 15 16 // 构造一个空的线性表 17 bool InitSqList(SqList *sqlist); 18 19 // 在指定线性表存在的前提下: 20 21 // 销毁指点线性表 22 void DestorySqList(SqList *sqlist); 23 24 // 判断线性表是否为空 25 bool SqListEmpty(SqList *sqlist); 26 27 // 获取指定线性表中元素个数 28 int SqListLength(SqList *sqlist); 29 30 // 在线性表中指定位置元素存在的情况下返回该元素值 31 bool GetElem(SqList *sqlist, int i, ElemType *elem); 32 33 // 返回指定元素在线性表中第一次出现的位置 34 bool LocateElem(SqList *sqlist, ElemType elem, int *pos); 35 36 // 若指定元素在线性表中存在,且不是线性表中的第一个元素,返回该指定元素第一次出现位置的前一个元素 37 bool PriorElem(SqList *sqlist, ElemType cur_elem, ElemType *pr_elem); 38 39 // 若指定元素在线性表中存在,且不是线性表中的最后一个元素,返回该指定元素第一次出现位置的后一个元素 40 bool NextElem(SqList *sqlist, ElemType cur_elem, ElemType *next_elem); 41 42 // 在线性表指定位置插入新元素 43 bool SqListInsert(SqList *sqlist, int pos, ElemType elem); 44 45 // 删除线性表指定位置元素,并返回该元素 46 bool SqListDelete(SqList *sqlist, int pos, ElemType *elem); 47 48 // 遍历线性表,此处实现仅仅是将其输出到标准输出,若需要,可选择输出到文件等 49 void SqListTraverse(SqList *sqlist); 50 51 // 增加线性表容量 52 bool SqListExtend(SqList *sqlist); 53 54 // 将两个排好序的顺序表合并(默认从大到小排序) 55 bool MergeSqList(SqList *sq1, SqList *sq2, SqList *mersq);
1 bool InitSqList(SqList *sqlist) 2 { 3 sqlist->elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType)); 4 5 if (!sqlist->elem) 6 return false; // malloc失败 7 8 sqlist->length = 0; 9 sqlist->listsize = LIST_INIT_SIZE; // 线性表初始长度 10 11 return true; 12 } 13 14 void DestorySqList(SqList *sqlist) 15 { 16 free(sqlist->elem); 17 sqlist->elem = NULL; 18 sqlist->length = 0; 19 sqlist->listsize = 0; 20 // 此处释放分配给该线性表的存储空间,并将该线性表的length、listsize清零 21 } 22 23 bool SqListEmpty(SqList *sqlist) 24 { 25 if (sqlist->length) 26 return false; 27 28 return true; 29 } 30 31 int SqListLength(SqList *sqlist) 32 { 33 return sqlist->length; 34 } 35 36 bool GetElem(SqList *sqlist, int pos, ElemType *elem) 37 { 38 if (pos > sqlist->length || pos < 1) 39 return false; 40 41 *elem = sqlist->elem[pos - 1]; 42 43 return true; 44 } 45 46 bool LocateElem(SqList *sqlist, ElemType elem, int *pos) 47 { 48 int i = 0; 49 for (; i < sqlist->length; i++) { 50 if (sqlist->elem[i] == elem) { 51 *pos = i + 1; // 返回elem第一次出现的位置 i+1 52 return true; 53 } 54 } 55 56 // 线性表中不存在元素elem 57 *pos = 0; 58 return false; 59 } 60 61 bool PriorElem(SqList *sqlist, ElemType cur_elem, ElemType *pr_elem) 62 { 63 int i = 0; 64 65 for (; i < sqlist->length; i++) { 66 if (i != 0 && sqlist->elem[i] == cur_elem) { 67 *pr_elem = sqlist->elem[i - 1]; 68 return true; 69 } 70 } 71 72 return false; 73 } 74 75 bool NextElem(SqList *sqlist, ElemType cur_elem, ElemType *next_elem) 76 { 77 int i = 0; 78 79 for (; i < sqlist->length - 1; i++) { 80 if (cur_elem == sqlist->elem[i]) { 81 *next_elem = sqlist->elem[i + 1]; 82 return true; 83 } 84 } 85 86 return false; 87 } 88 89 bool SqListInsert(SqList *sqlist, int pos, ElemType elem) 90 { 91 // 若在线性表已满的情况下插入元素,需要先对线性表做扩从操作 92 if (pos < 1 || pos > sqlist->length + 1) 93 return false; // 插入位置非法 94 95 if (sqlist->length == sqlist->listsize) { 96 if (!SqListExtend(sqlist)) { 97 return false; // realloc出错 98 } 99 } 100 101 int i = sqlist->length; 102 for (; i >= pos; i--) { 103 sqlist->elem[i] = sqlist->elem[i - 1]; 104 } 105 106 sqlist->elem[pos - 1] = elem; 107 sqlist->length++; 108 109 return true; 110 } 111 112 bool SqListDelete(SqList *sqlist, int pos, ElemType *elem) 113 { 114 if (pos < 1 || pos > sqlist->length) { 115 return false; // 删除位置出错 116 } 117 118 int i = pos - 1; 119 *elem = sqlist->elem[i]; 120 for (; i < sqlist->length - 1; i++) { 121 sqlist->elem[i] = sqlist->elem[i + 1]; 122 } 123 124 sqlist->length--; 125 126 return true; 127 } 128 129 void SqListTraverse(SqList *sqlist) 130 { 131 int i; 132 133 for (i = 0; i < sqlist->length; i++) { 134 printf("%d\n", sqlist->elem[i]); 135 } 136 } 137 138 bool SqListExtend(SqList *sqlist) 139 { 140 ElemType *newbase = (ElemType *)realloc(sqlist->elem, (sqlist->listsize + LISTINCREMENT) * sizeof(ElemType)); 141 142 if (!newbase) 143 return false; 144 145 sqlist->elem = newbase; 146 sqlist->listsize += LISTINCREMENT; 147 148 return true; 149 } 150 151 bool MergeSqList(SqList *sq1, SqList *sq2, SqList *mersq) 152 { 153 mersq->elem = (ElemType *)malloc((sq1->length + sq2->length) * sizeof(ElemType)); 154 155 if (!mersq->elem) 156 return false; // malloc失败 157 158 mersq->length = 0; 159 mersq->listsize = sq1->length + sq2->length; 160 161 int pos = 1, j = 0, k = 0; 162 163 while (j < sq1->length - 1 && k < sq2->length) { 164 if (sq1->elem[j] <= sq2->elem[k]) { 165 if (!SqListInsert(mersq, pos++, sq1->elem[j])) 166 return false; // 插入错误 167 168 ++j; 169 } 170 else { 171 if (!SqListInsert(mersq, pos++, sq2->elem[k])) 172 return false; // 插入错误 173 174 ++k; 175 } 176 } 177 178 // 插入剩余元素 179 while (j < sq1->length) { 180 if (!SqListInsert(mersq, pos++, sq1->elem[j])) 181 return false; // 插入错误 182 183 ++j; 184 } 185 186 while (k < sq2->length) { 187 if (!SqListInsert(mersq, pos++, sq2->elem[k])) 188 return false; // 插入错误 189 190 ++k; 191 } 192 193 return true; 194 }
测试程序与测试结果:
#include "linear_list.h" #include "normalHead.h" int main(void) { SqList sqlist; if (InitSqList(&sqlist)) printf("Init.. \n"); int i; for (i = 0; i < 10; i++) { SqListInsert(&sqlist, i + 1, i + 1); } printf("Length = %d\n", SqListLength(&sqlist)); if (!SqListEmpty(&sqlist)) { printf("Not Empty!\n"); } int ele; if (GetElem(&sqlist, 5, &ele)) printf("ele = %d\n", ele); int pos; if (LocateElem(&sqlist, ele, &pos)) printf("pos = %d\n", pos); int pre; if (PriorElem(&sqlist, 5, &pre)) printf("pre = %d\n", pre); int next; if (NextElem(&sqlist, 5, &next)) printf("next = %d\n", next); int del; if (SqListDelete(&sqlist, 5, &del)) printf("del = %d\n", del); SqListTraverse(&sqlist); printf("\n"); SqList sq1, sq2, sq3; InitSqList(&sq1); InitSqList(&sq2); i = 1; for (; i <= 5; ++i) { SqListInsert(&sq1, i, 2 * i - 1); SqListInsert(&sq2, i, 2 * i); } MergeSqList(&sq1, &sq2, &sq3); SqListTraverse(&sq1); printf("\n"); SqListTraverse(&sq2); printf("\n"); SqListTraverse(&sq3); getchar(); return 0; } /* 输出: Init.. Length = 10 Not Empty! ele = 5 pos = 5 pre = 4 next = 6 del = 5 1 2 3 4 6 7 8 9 10 1 3 5 7 9 2 4 6 8 10 1 2 3 4 5 6 7 9 8 10 */
转载请注明出处