顺序表的优点:
支持随机访问
顺序表的缺点:
1、插入或删除时移动数据存在消耗;
2、空间不足时需要扩容,扩容存在消耗;
3、为了防止频繁扩容,扩容时通常扩容到之前的几倍,难免存在空间浪费
C语言实现动态顺序表
文件一 SeqList.h
1、结构体的定义
2、各类接口函数的声明
//文件一 SeqList.h #pragma once #includetypedef int SLDataType;//统一管理存入数据的类型 typedef struct SeqList { SLDataType *a; //开辟的空间的首地址 int size; //当前存入数据的数目 int capacity; //当前空间的总容量 }SL; void SeqListInit(SL* p); //顺序表的初始化 void SeqListCheckCapacity(SL* p); //检查空间的总容量 void SeqListPushBack(SL* p,SLDataType x); //表尾插入 void SeqListPopBack(SL* p); //表尾删除 void SeqListPushFront(SL* p,SLDataType x); //表头插入 void SeqListPopFront(SL* p); //表头删除 void SeqListInsert(SL* p,int pos,SLDataType x); //选择插入 void SeqListErase(SL* p,int pos); //选择删除 int SeqListFind(SL* p,SLDataType x); //查找数据 void SeqListPrint(SL* p); //打印数据 void SeqListDestroy(SL* p); //释放空间
文件二 SeqList.c
各类接口函数的实现
//文件二 SeqList.c #include#include #include"SeqList.h" void SeqListInit(SL* p) //表的初始化 { p->a=NULL; p->size=p->capacity=0; } void SeqListCheckCapacity(SL* p) //检查空间的总容量 { if(p->size==p->capacity) { //使用realloc扩容,realloc的第二个参数是内存空间的字节数 //首次扩容到4,为了防止频繁扩容,所以之后都是扩容到之前的两倍 int new_capacity=p->capacity==0?4:p->capacity*2; SLDataType *tem=(SLDataType *)realloc(p->a,new_capacity*sizeof(SLDataType)); if(tem==NULL)//扩容失败 { printf("Realloc fail!n"); exit(-1);//非正常退出当前运行的程序 } p->a=tem; p->capacity=new_capacity; } } void SeqListPushBack(SL* p,SLDataType x) //表尾插入 { SeqListCheckCapacity(p);//添加数据前检查空间的总容量 p->a[p->size]=x;//size比当前存储有数据的空间的最大下标值大1 p->size++; } void SeqListPopBack(SL* p) //表尾删除 { assert(p->size>0); p->size--; //如果以后有添加数据的情况,之前的表尾数据会被覆盖 //之前的表尾数据无法被函数SeqListPrint(打印数据)访问 } void SeqListPushFront(SL* p,SLDataType x) //表头插入 { SeqListCheckCapacity(p);//添加数据前检查空间的总容量 int end=p->size-1; while(end>=0) { p->a[end+1]=p->a[end]; end--; } //从下标为p->size-1处开始,从后往前把每一个数据都往后移动一个单位 p->a[0]=x; p->size++; } void SeqListPopFront(SL* p) //表头删除 { assert(p->size>0); int begin=1; while(begin size) { p->a[begin-1]=p->a[begin]; begin++; } //从下标为1处开始,从前往后把每一个数据都往前移动一个单位,表头数据被覆盖 p->size--; } void SeqListInsert(SL* p,int pos,SLDataType x)//选择插入 { assert(pos>=0&&pos<=p->size); SeqListCheckCapacity(p);//添加数据前检查空间的总容量 int end=p->size-1; while(end>=pos) { p->a[end+1]=p->a[end]; end--; } p->a[pos]=x; p->size++; } void SeqListErase(SL* p,int pos) //选择删除 { assert(pos>=0&&pos size); int begin=pos+1; while(begin size) { p->a[begin-1]=p->a[begin]; begin++; } p->size--; } int SeqListFind(SL* p,SLDataType x) //查找数据 { int i; for(i=0;i size;i++) if(p->a[i]==x) return i;//若有多个x,返回的是最小的下标 return -1; } void SeqListPrint(SL* p) //打印数据 { int i; for(i=0;i size;i++) printf("%d ",p->a[i]); printf("n"); } void SeqListDestroy(SL* p) //释放空间 { free(p->a); p->a=NULL; p->size=p->capacity=0; }
文件三 SeqListTest.c
测试用例
//文件三 SeqListTest.c #include#include"SeqList.h" void SeqListTest() { SL sl; //顺序表的初始化 SeqListInit(&sl); SeqListPushBack(&sl,0); SeqListPushBack(&sl,7); SeqListPushBack(&sl,1); SeqListPushBack(&sl,9); SeqListPushBack(&sl,0); SeqListPushBack(&sl,0); printf("测试1(表尾插入):n"); SeqListPrint(&sl); printf("-------------------------n"); SeqListPopBack(&sl); SeqListPopBack(&sl); printf("测试2(表尾删除):n"); SeqListPrint(&sl); printf("-------------------------n"); SeqListPushFront(&sl,2); SeqListPushFront(&sl,2); SeqListPushFront(&sl,0); SeqListPushFront(&sl,2); SeqListPushFront(&sl,0); SeqListPushFront(&sl,0); printf("测试3(表头插入):n"); SeqListPrint(&sl); printf("-------------------------n"); SeqListPopFront(&sl); SeqListPopFront(&sl); printf("测试4(表头删除):n"); SeqListPrint(&sl); printf("-------------------------n"); SeqListInsert(&sl,5,0); SeqListInsert(&sl,9,0); printf("测试5(选择插入):n"); SeqListPrint(&sl); printf("-------------------------n"); SeqListErase(&sl,9); SeqListErase(&sl,5); printf("测试6(选择删除):n"); SeqListPrint(&sl); printf("-------------------------n"); printf("测试7(查找数据):n"); printf("2的最小下标是:%dn",SeqListFind(&sl,2)); printf("7的最小下标是:%dn",SeqListFind(&sl,7)); printf("9的最小下标是:%dn",SeqListFind(&sl,9)); printf("-------------------------n"); printf("测试8(输出最终结果):n"); SeqListPrint(&sl); //可以在此处添加更多测试 //释放空间 SeqListDestroy(&sl); } int main() { SeqListTest(); return 0; }
测试用例输出效果图



