一、顺序表的概念和结构
1.1 线性表
线性表( linearlist )是n个具有相同特性的数据元素的有限序列。线性表是⼀种在实际中⼴泛使⽤的数据结构,常⻅的线性表:顺序表、链表、栈、队列、字符串...
线性表在逻辑上是线性结构,也就说是连续的⼀条直线。但是在物理结构上并不⼀定是连续的,
线性表在物理上存储时,通常以数组和链式结构的形式存储。
案例:蔬菜分为绿叶类、⽠类、菌菇类。线性表指的是具有部分相同特性的⼀类数据结构的集合
二、顺序表分类
顺序表和数组的区别
◦ 顺序表的底层结构是数组,对数组的封装,实现了常⽤的增删改查等接⼝
顺序表分类
◦ 静态顺序表
概念:使⽤定⻓数组存储元素
typedef int SLDataType
#define N 7
typedef struct SeqList{
SLDataType a[N]; //定长数组
int size; //有效数据个数
}
静态顺序表缺陷:空间给少了不够⽤,给多了造成空间浪费
◦ 动态顺序表(可增容)
typedef struct SeqList{
SLDataType* a;
int size; //有效数据个数
int capacity; //空间容量
}
三、动态顺序表的实现
//SeqList.h
#define INIT_CAPACITY 4
typedef int SLDataType;
// 动态顺序表 -- 按需申请
typedef struct SeqList
{
SLDataType* a;
int size; // 有效数据个数
int capacity; // 空间容量
}SL;
//初始化和销毁
void SLInit(SL* ps);
void SLDestroy(SL* ps);
void SLPrint(SL* ps);
//扩容
void SLCheckCapacity(SL* ps);
//头部插⼊删除 / 尾部插⼊删除
void SLPushBack(SL* ps, SLDataType x);
void SLPopBack(SL* ps);
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);
//指定位置之前插⼊/删除数据
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);
int SLFind(SL* ps, SLDataType x);
//SeqList.c
#include"SeqList.h"
//初始化和销毁
void SLInit(SL* ps) {
ps->arr = NULL; //不是int 而是Info类型
ps->size = ps->capacity = 0;
}
void SLCheckCapacity(SL* ps) {
if (ps->size == ps->capacity) {
int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
SLDataType* tmp = (SLDataType*)realloc(ps->arr, newCapacity * sizeof(SLDataType));
if (tmp == NULL) {
perror("realloc fail!");
exit(1);
}
//扩容成功
ps->arr = tmp;
ps->capacity = newCapacity;
}
}
//顺序表的头部/尾部插入
void SLPushBack(SL* ps, SLDataType x) {
//断言--粗暴的解决方式
//assert(ps != NULL);
assert(ps);
//if判断--温柔的解决方式
//if (ps == NUL