顺序表的尾删
有了尾插也一定有尾删,直接看代码。
void SLPopBack(SL* psl) { assert(psl); assert(psl->size>0); psl->size--; }
由于是尾部删除,我们只需要将最后一个数据丢失即可,我们舍弃最后一个数据,只需要通过psl指针找到的size–即可。
顺序表的头删
有了头插也一定有头删,看一下吧。
void SLPopFront(SL* psl) { assert(psl); assert(psl->size>0); int begin=1; while(begin<psl->size) { psl->a[begin-1]=psl->a[begin]; begin++; } psl->size--; }
首先,依然是断言保证传入指针非空,保证有效数据个数不为0,之后我们需要从开始将第二个元素赋给第一个元素,再把第三个元素赋给第二个元素,这样下去,就能实现头删,我们定义一个begin变量为1,在while循环中将begin个元素赋给begin-1个元素,之后begin++,实现赋值循环。
顺序表的任意位置插入
有了头插和尾插,我们接下里在任意位置插入,直接上代码。
void SLInsert(SL* psl,int pos,SLDataType x) { assert(psl); assert(pos>0&&pos<=psl->size); SLCheckCapacity(&psl); int end=psl->size-1; while(end>=pos) { psl->a[end+1]=psl->a[end]; end--; } psl->a[pos]=x; psl->size++; }
首先,我们需要保证传入指针非空,传入pos合法,以及容量足够,之后进行数据移动,和头插十分相似,知识不懂pos位置之前的数据,所以只需要将0替换为pos即可。之后将x存储到第pos个位置中去,psl所指向的size++即可。
顺序表的任意位置删除
有任意位置插入,就可以有任意位置删除,我们直接看代码。
void SLErase(SL* psl, int pos) { assert(psl); assert(pos>0&&pos<=psl->size) int begin=pos+1; while(begin<psl->size) { psl->a[begin-1]=psl->a[begin]; begin++; } psl->size--; }
首先,依然是断言,保证pos的合法,之后和头删的操作其实很相似,我们把第pos个位置看成首地址去进行头删即可。
顺序表的查找
我们可能会需要查找顺序表的某个元素,来实现一下
void SLFind(SL* psl,SLDataType x) { assert(psl); for(int i=0;i<psl->size;i++) { if(psl->a[i]==x) { return i; } } return -1; }
直接,遍历之后找到下表就返回i,没有就返回-1。
代码与总结
顺序表可以帮助我们实现一些信息的管理,有助于我们写一些学生信息管理等等,相信大家都能够做出来这样的系统,就不再展示,以后有机会会展示给大家。
最后给大家看一下,鄙人的代码实现,是封装为3个文件的。
SeqList.h
#pragma once #include<stdio.h> #include<stdlib.h> #include<assert.h> typedef int SLDataType; typedef struct SeqList { SLDataType* a; int size; //有效数据 int capacity; //空间容量 }SL; void SLInit(SL* psl);//初始化顺序表 void SLDestroy(SL* psl);//销毁顺序表 void SLPushBack(SL* psl, SLDataType x);//头插 void SLPushFront(SL* psl, SLDataType x);//尾插 void SLPrint(SL* psl);//打印顺序表 void SLCheckCapacity(SL* psl);//增容 void SLPopBack(SL* psl);//尾删 void SLPopFront(SL* psl);//头删 // 任意下标位置的插入删除 void SLInsert(SL* psl, int pos, SLDataType x); void SLErase(SL* psl, int pos);
SeqList.c
#define _CRT_SECURE_NO_WARNINGS #include"SeqList.h" void SLInit(SL* psl) { assert(psl); psl->a = NULL; psl->size = 0; psl->capacity = 0; } void SLDestroy(SL* psl) { assert(psl); if (psl->a != NULL) { free(psl->a); psl->a = NULL; psl->size = 0; psl->capacity = 0; } } void SLPrint(SL* psl) { assert(psl); for (int i = 0; i < psl->size; i++) { printf("%d ", psl->a[i]); } printf("\n"); } void SLCheckCapacity(SL* psl) { assert(psl); if (psl->size == psl->capacity) { int newcapacity = psl->capacity == 0 ? 4 : psl->capacity * 2; SLDataType* tmp = (SLDataType*)realloc(psl->a,sizeof(SLDataType) * newcapacity); if (tmp == NULL) { perror("realloc fail"); return; } psl->a = tmp; psl->capacity = newcapacity; } } void SLPushBack(SL* psl, SLDataType x) { assert(psl); SLCheckCapacity(psl); psl->a[psl->size] = x; psl->size++; } void SLPushFront(SL* psl, SLDataType x) { assert(psl); SLCheckCapacity(psl); int end = psl->size-1; while (end >= 0) { psl->a[end+1] = psl->a[end]; end--; } psl->a[0] = x; psl->size++; } void SLPopBack(SL* psl) { assert(psl); assert(psl->size > 0); psl->size--; } void SLPopFront(SL* psl) { assert(psl); assert(psl->size > 0); int begin = 1; while (begin < psl->size) { psl->a[begin - 1] = psl->a[begin]; begin++; } psl->size--; } // 任意下标位置的插入删除 void SLInsert(SL* psl, int pos, SLDataType x) { assert(psl); assert(pos > 0 && pos <= psl->size); SLCheckCapacity(psl); int end = psl->size - 1; while (end >=pos) { psl->a[end+1] = psl->a[end]; end--; } psl->a[pos] = x; psl->size++; } void SLErase(SL* psl, int pos) { assert(psl); assert(pos > 0 && pos <= psl->size); int begin = pos+1; while (begin <psl->size) { psl->a[begin-1] = psl->a[begin]; begin++; } psl->size--; }
还有一个test.c的文件是用来测试顺序表的,大家自行测试即可,谢谢大家的观看!