线性表
线性表(linear list)是n个具有相同特性元素的有限序列 。线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串……
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。
顺序表
它是最简单的数据结构,也是最常用的数据结构——他的作用就是将数据存起来。
概念:顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
顺序表一般可分为:
1.静态顺序表:使用定长数据存储。
2.动态顺序表:使用动态开辟的数组存储。
下面的代码实现的是动态顺序表
结构定义
1 2 3 4 5 6 7
| typedef int SeqListDataType; typedef struct SeqList { SeqListDataType* arry; int size; int capacity; }SeqList;
|
![image-20210605131238279](/images/%E7%BA%BF%E6%80%A7%E8%A1%A8%E4%B9%8B%E9%A1%BA%E5%BA%8F%E8%A1%A8.assets/image-20210605131238279.png)
初始化
1 2 3 4 5 6
| void SeqListInit(SeqList* ps) { ps->arry = NULL; ps->size = 0; ps->capacity = 0; }
|
销毁
严格来说空间用完之后就要销毁,如果malloc开辟的空间不销毁就会存在内存泄漏。
1 2 3 4 5 6
| void SeqListDestory(SeqList* ps) { free(ps->arry); ps->arry = NULL; ps->capacity = ps->size = 0; }
|
打印
1 2 3 4 5 6 7
| void SeqListPrint(SeqList* ps) { for (int i = 0; i < ps->size; i++) { printf("%d ", ps->arry[i]); } }
|
扩展空间
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
| void SeqListCheckCapacity(SeqList* ps) { if (ps->size == ps->capacity) { int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2; SeqListDataType* tmp = (SeqListDataType*)realloc(ps->arry, newCapacity * sizeof(SeqListDataType)); if (tmp == NULL) { printf("realloc is fail!"); exit(-1); } else { ps->arry = tmp; ps->capacity = newCapacity; } } }
|
尾插
1 2 3 4 5 6 7
| void SeqListPushBack(SeqList* ps,SeqListDataType x) { SeqListCheckCapacity(ps); ps->arry[ps->size] = x; ps->size++; }
|
头插
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| void SeqListPushFront(SeqList* ps, SeqListDataType x) { SeqListCheckCapacity(ps); int end = ps->size - 1; while (end >= 0) { ps->arry[end + 1] = ps->arry[end]; end--; } ps->arry[0] = x; ps->size++; }
|
尾删
1 2 3 4 5 6 7 8
| void SeqListPopBack(SeqList* ps) { assert(ps->size > 0); ps->size--; }
|
头删
1 2 3 4 5 6 7 8 9 10 11 12 13
| void SeqListPopFront(SeqList* ps) { assert(ps->size > 0); int start = 1; while (start < ps->size) { ps->arry[start - 1] = ps->arry[start]; start++; } ps->size--; }
|
在指定位置插入数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| void SeqListInsert(SeqList* ps, int pos, SeqListDataType x) { assert(pos < ps->size); SeqListCheckCapacity(ps); int end = ps->size - 1; while (end >= pos) { ps->arry[end + 1] = ps->arry[end]; end--; } ps->arry[pos] = x; ps->capacity++; }
|
删除指定位置数据
1 2 3 4 5 6 7 8 9 10 11 12
| void SeqListErase(SeqList* ps, int pos) { assert(pos < ps->size); int start = pos + 1; while (start < ps->size) { ps->arry[start - 1] = ps->arry[start]; start++; } ps->size--; }
|
查找
1 2 3 4 5 6 7 8 9 10 11 12
| int SeqListFind(SeqList* ps, SeqListDataType x) { for (int i = 0; i < ps->size; i++) { if (ps->arry[i] == x) { return i; } } return -1; }
|
修改
1 2 3 4 5
| void SeqListModity(SeqList* ps, int pos, SeqListDataType x) { assert(pos < ps->size); ps->arry[pos] = x; }
|