一.定义
线性表(List):零个或多个数据元素的有限序列。
线性表首先它是一个序列,也就是说元素之间是有先来后到的。
若元素存在多个,则第一个元素无前驱,而最后一个元素无后继,其他元素都只有一个直接前驱,和只有一个直接后继。
线性表元素的个数n(n>=0)定义为线性表的长度,当n=0时,称为空表。
二.线性表的存储结构
1. 线性表的顺序存储结构
(1)顺序存储:
用一组地址连续连续的存储单元来依次存放线性表中的数据。
顺序存储结构示意图
- 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组
上完成数据的增删查改。
- 顺序表:可动态增长的数组,要求数据是连续存储的
(2)顺序表的定义
1. 静态顺序表:使用定长数组存储元素
缺陷:给小了不够用,给大了可能浪费,非常不实用
1 2 3 4 5 6 7 8
| #define N 10 typedef int SLDataType;
typedef struct SeqList { SLDataType array[N]; size_t size; }SeqList;
|
2. 动态顺序表:使用动态开辟的数组存储元素
动态顺序表可根据我们的需要分配空间大小
size 表示当前顺序表中已存放的数据个数
capacity 表示顺序表总共能够存放的数据个数
typedef int SLDataType; //类型重命名,后续要存储其它类型时方便更改
1 2 3 4 5 6
| typedef struct SeqList { SLDataType* a; size_t size; size_t capacity; }SeqList;
|
(3)顺序表的接口实现
首先新建一个工程,此次用的是动态顺序表
- SeqList.h(顺序表的类型定义、接口函数声明、引用的头文件)
- SeqList.cpp(顺序表接口函数的实现)
- Test.cpp(主函数、测试顺序表各个接口功能)
1. SeqList.h 头文件代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| #pragma once
#include<stdio.h> #include<assert.h> #include<stdlib.h>
typedef int SLDataType;
typedef struct SeqList { SLDataType* a; size_t size; size_t capacity; }SeqList;
void SeqListInit(SeqList* psl);
void SeqListDestory(SeqList* psl);
void CheckCapacity(SeqList* psl);
void SeqListPushBack(SeqList* psl, SLDataType x);
void SeqListPopBack(SeqList* psl);
void SeqListPushFront(SeqList* psl, SLDataType x);
void SeqListPopFront(SeqList* psl);
void SeqListPrint(const SeqList* psl);
int SeqListFind(const SeqList* psl, SLDataType x);
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x);
void SeqListErase(SeqList* psl, size_t pos);
size_t SeqListSize(const SeqList* psl);
void SeqListAt(SeqList* psl, size_t pos, SLDataType x);
|
2. SeqList.c 中各个接口函数的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
|
void SeqListInit(SeqList* psl) { assert(psl != NULL);
psl->a = NULL; psl->size = 0; psl->capacity = 0; }
2、销毁(释放)顺序表 记得一定要加上断言,防止传进来的指针为空
void SeqListDestory(SeqList* psl) { assert(psl != NULL);
free(psl->a); psl->a = NULL; psl->size = 0; psl->capacity = 0; }
void CheckCapacity(SeqList* psl) { assert(psl != NULL);
if (psl->size == psl->capacity) { size_t newcapacity; if (psl->capacity == 0) newcapacity = psl->capacity = 4; else newcapacity = 2 * psl->capacity; SLDataType* p = (SLDataType*)realloc(psl->a, newcapacity*sizeof(SLDataType)); if (p == NULL) { perror("realloc"); exit(-1); } psl->a = p; psl->capacity = newcapacity; } }
void SeqListPushBack(SeqList* psl, SLDataType x) { assert(psl != NULL);
CheckCapacity(psl);
psl->a[psl->size] = x; psl->size++; }
void SeqListPopBack(SeqList* psl) { assert(psl != NULL); assert(psl->size > 0);
psl->size--; }
void SeqListPushFront(SeqList* psl, SLDataType x) { assert(psl); CheckCapacity(psl); int i = 0; for (i = psl->size - 1; i >= 0; i--) { psl->a[i + 1] = psl->a[i]; } psl->a[0] = x; psl->size++; }
void SeqListPopFront(SeqList* psl) { assert(psl); assert(psl->size > 0);
int i = 0; for (i = 1; i < psl->size; i++) { psl->a[i - 1] = psl->a[i]; } psl->size--; }
void SeqListPrint(const SeqList* psl) { assert(psl != NULL);
if (psl->size == 0) { printf("顺序表为空\n"); return; }
int i = 0; for (i = 0; i < psl->size; i++) { printf("%d ", psl->a[i]); } printf("\n"); }
int SeqListFind(const SeqList* psl, SLDataType x) { assert(psl);
int i = 0; for (i = 0; i < psl->size; i++) { if (psl->a[i] == x) { return i; } } return -1; }
int i = 0; for (i = psl->size - 1; i >= pos; i--) psl->a[i + 1] = psl->a[i];
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x) { assert(psl); assert(pos >= 0 && pos <= psl->size);
CheckCapacity(psl);
size_t i = 0; for (i = psl->size; i > pos; i--) { psl->a[i] = psl->a[i - 1]; } psl->a[pos] = x; psl->size++; }
void SeqListErase(SeqList* psl, size_t pos) { assert(psl); assert(psl->size > 0); assert(pos >= 0 && pos < psl->size);
size_t i = 0; for (i = pos + 1; i < psl->size; i++) { psl->a[i - 1] = psl->a[i]; } psl->size--; }
size_t SeqListSize(const SeqList* psl) { assert(psl);
return psl->size; }
void SeqListAt(SeqList* psl, size_t pos, SLDataType x) { assert(psl); assert(psl->size > 0); assert(pos >= 0 && pos < psl->size);
psl->a[pos] = x; }
|