数据结构与算法-顺序表专题
一. 前言
1. 数据结构
数据结构是计算机存储、组织数据的方式。
二. 顺序表
2.1 顺序表的概念和结构
2.1.1 线性表
-线性表是具有相同特性的数据结构的集合。(常见线性表:顺序表、栈、队列、字符串...)
-线性表有两种结构,分别是物理结构和逻辑结构
-线性表的物理结构不一定连续,但是逻辑结构是连续的。
-线性表在逻辑上是线性结构,也就是说是连续的一条直线
-而顺序表是线性表的一种,顺序表的物理结构和逻辑结构全是连续的。
2.2 顺序表的分类
-顺序表的底层结构是数组,对于数组的封装,实现了常用的增删改查等接口。
-顺序表分为静态顺序表和动态顺序表
2.2.1 静态顺序表
静态顺序表是使用定长数组存储元素
代码创建:
//静态顺序表的创建
struct SeqList
{int arr[10];//定数组int size;//有效元素的个数int capaciity;//开辟空间的大小
};
缺点:空间固定了,太小不够用,太大空间浪费
2.2.2 动态顺序表
代码创建:
//动态顺序表的创建,并顺便将结构体重命名为SL
typedef struct S
{SLDateType* arr;//指向数组的指针int size;//有效数据个数int capacity;//开辟的空间大小
}SL;
优点:空间可改变,不会被限制
所以一般我们创建顺序表都是创建动态顺序表
2.3 动态顺序表的实现
2.3.1 初始化
首先在SeqList.h的头文件进行函数的声明
//动态顺序表的初始化
void SLInit(SL* ps);
再在SeqList.c的源文件进行函数的实现:
//动态顺序表的初始化
void SLInit(SL* ps) //注意此处是传地址,不是传值
{ps->arr = NULL;ps->size = ps->capacity = 0;
}
//传地址是因为初始化需要改变实际参数的数值
// 而传值没有权限改变实际参数的数值
然后在add.c的实际运行源文件中进行函数的使用:
SL sl;
SLInit(&sl);
2.3.2 销毁
SeqList.h:
//动态顺序表的销毁
void SLDestroy(SL* ps);
SeqList.c
//动态顺序表的销毁
void SLDestroy(SL* ps)
{if (ps->arr)//判断申请的数组是否有空间{free(ps);}ps->arr = NULL;ps->size = ps->capacity = 0;
}
2.3.3 尾插
继续和上述一样,在头文件进行声明
SeqList.c:
//尾插
void SLPushBack(SL* ps, SLDataType x)
{//如果输入的指针是空指针//第一种判断方式/*if (ps){return;}*///直接返回//或者第二种判断方式assert(ps);//直接报错//看空间够不够if (ps->capacity == ps->size){//空间不够//申请空间int newcapacity = ps->capacity = 0 ? 4 : 2 * ps->capacity;//判断capacity是否为0SLDataType* temp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType);if (temp == NULL)//检查是否增容成功{perror("realloc files");exit(1);}//增容成功后ps->capacity = newcapacity;ps->arr = temp;ps->arr[ps->size++] = x;}}
注意注释,仔细注意细节,说明了很多坑。
2.3.4 头插
SeqList.c:
//头插
void SLPushFront(SL* ps, SLDataType x)
{assert(ps);SLCheckCapacity(ps);int i = 0;for (i = 0; i > 0; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[0] = x;ps->size++;//只要插入数据,就不要忘了size++(扩容内存)
}
其中的SLCheckCapacity(ps)函数是检查内存是否够用的整合:
void SLCheckCapacity(SL*ps)//检查空间
{if (ps->capacity == ps->size){//空间不够//申请空间int newcapacity = ps->capacity = 0 ? 4 : 2 * ps->capacity;//判断capacity是否为0SLDataType* temp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType);if (temp == NULL)//检查是否增容成功{perror("realloc files");exit(1);}}}
2.3.5 尾删
函数实现:
//尾删
void SLPopBack(SL* ps)
{assert(ps);assert(ps->size);//防止顺序表为空--ps->size;
}
2.3.6 前删
函数实现:
//前删
void SLPopFront(SL* ps)
{assert(ps);assert(ps->size);//防止顺序表为空for (int i = 0; i < ps->size - 1; i++){ps->arr[i] = ps->arr[i + 1]; //arr[size-2] = arr[size-1]}ps->size--;
}