C语言 C C语言顺序表 HappyLadySauce 2025-04-09 2025-04-14 顺序表简述 顺序表是用一段物理地址连续的储存单元依次存储数据元素的线性结构,一般情况采用数组存储。
在数组上完成增删查改。
顺序表分类与实现 静态顺序表 使用定长的数组存储元素
静态实现 1 2 3 4 5 6 7 8 #define N 100 typedef int ListData; typedef struct SeqList { ListData* data[N]; int size; }SL;
静态顺序表只能存储一定量的数据,结构也比较简单。
容量(N)有时给小了不够用,给大了会有浪费,不好控制。
所以就提出了动态的顺序表。
静态顺序表的基本操作和动态差不多,这里重点描述动态顺序表,静态就不再赘述了。
动态顺序表 使用动态开辟的数组存储元素
动态实现 1 2 3 4 5 6 7 8 typedef int ListData;typedef struct SeqList { ListData* data; int size; int capacity; }SL;
动态顺序表能根据数据量调整存储数据容量的大小
动态顺序表的基本操作 基本操作:增删查改
增,有头插,尾插
删,有头删,尾删
查,就是一般操作
改,需要自己手动配置
初始化顺序表
1 2 3 4 5 6 7 8 9 10 void InitSeqList (SL* SL) { assert (SL); SL->size = 0 ; SL->capacity = 4 ; ListData* NewList = (ListData*)malloc (sizeof (ListData) * SL->capacity); assert (NewList); SL->data = NewList; }
销毁顺序表
1 2 3 4 5 6 7 8 9 10 void DestroySeqList (SL* SL) { assert (SL); SL->size = 0 ; SL->capacity = 0 ; assert (SL->data); free (SL->data); SL->data = NULL ; }
在顺序表中增加元素
在增加元素时,我们要先考虑在增加元素时,有可能会超过当前顺序表的容量,这个时候我们就要进行扩容操作,防止数据溢出。
1 2 3 4 5 6 7 8 9 10 11 void CheckCapacity (SL* psl) { if (psl->size < psl->capacity) return ; psl->capacity *= 2 ; ListData* NewList = (ListData*)realloc (psl->data, sizeof (ListData) * psl->capacity); assert (NewList); psl->data = NewList; }
增加元素
我们应该在哪增加元素,在内存块的中间?前面?后面?
我们并不清楚实际中会在哪插入元素。
如果是在顺序表中的其他位置(pos),我们则需要去这个位置进行插入元素(x)
在顺序表pos位置插入元素
1 2 3 4 5 6 7 8 9 10 11 12 13 void SeqListInsert (SL* psl, int pos, ListData x) { assert (psl); assert (pos < (psl->size + 1 )); CheckCapacity (psl); for (int i = psl->size; i > pos; i--) { psl->data[i] = psl->data[i--]; } psl->data[pos] = x; psl->size++; }
在顺序表中删除元素
同样的在顺序表pos位置删除元素
1 2 3 4 5 6 7 8 9 10 void SeqListErase (SL* psl, int pos) { assert (psl); for (int i = pos; i < psl->size - 1 ; i++) { psl->data[i] = psl->data[i + 1 ]; } psl->size--; }
在顺序表中查找元素x,找到了返回下标
1 2 3 4 5 6 7 8 9 10 11 int SeqListFind (SL* psl, ListData x) { for (int i = 0 ; i < psl->size; i++) { if (psl->data[i] == x) { return i; } } return -1 ; }
头删头插,尾删尾插
这些都可以通过调用之前的在pos位置插入函数和删除pos位置函数来进行实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 void SeqListPushFront (SL* psl, ListData x) { SeqListInsert (psl, 0 , x); } void SeqListPushBack (SL* psl, ListData x) { SeqListInsert (psl, psl->size, x); } void SeqListPopFront (SL* psl) { SeqListErase (psl, 0 ); } void SeqListPopBack (SL* psl) { SeqListErase (psl, psl->size - 1 ); }
补充操作
打印
1 2 3 4 5 6 7 8 void SeqListPrint (SL* psl, int n) { for (int i = 0 ; i < n; i++) { printf ("%d " , psl->data[i]); } printf ("\n" ); }
求元素个数
1 2 3 4 int SeqListSize (SL* psl) { return psl->size; }
顺序表对改的要求不是很高,我就做个示范,大家看看就好
1 2 3 4 5 6 7 8 9 10 int n = SeqListSize (&s);while (n--){ int pos = SeqListFind (&s, 2 ); if (pos != -1 ) { SeqListInsert (&s, pos, 3 ); s.size--; } }
验证代码
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 int main () { SL s; InitSeqList (&s); SeqListPushFront (&s, 1 ); SeqListPushBack (&s, 2 ); SeqListPushBack (&s, 2 ); printf ("验证插入元素:" ); SeqListPrint (&s, SeqListSize (&s)); SeqListPopFront (&s); printf ("验证删除元素:" ); SeqListPrint (&s, SeqListSize (&s)); printf ("验证查找元素下标:" ); printf ("%d\n" , SeqListFind (&s, 1 )); int n = SeqListSize (&s); while (n--) { int pos = SeqListFind (&s, 2 ); if (pos != -1 ) { SeqListInsert (&s, pos, 3 ); s.size--; } } printf ("验证修改元素:" ); SeqListPrint (&s, SeqListSize (&s)); DestroySeqList (&s); return 0 ; }
谢谢观看,如果感觉还行可以点个赞,谢谢啦。QWQ