顺序表的概念及结构
线性表
线性表是具有相同特征的数据结构的集合
物理结构 不一定连续
逻辑结构 连续
顺序表
顺序表是线性表的一种,顺序表的底层是数组
物理结构 连续
逻辑结构 连续
顺序表分类
静态顺序表
struct SeqList
{
int arr[100];//定长数组
int size;//顺序表当前有效的数据结构
};
动态顺序表
struct SeqList
{
int* arr;
int size;//有效数据个数
int capacity;//空间大小
};
顺序表的实现
头文件
顺序表结构
创建顺序表
顺序表的初始化和销毁
顺序表扩容
顺序表的打印
头部插入删除 / 尾部插入删除
指定位置之前插入 / 删除
声明顺序表的方法
typedef int SLDataType;
//给int取别名,方便修改数组存储的数据类型
//例如将int类型修改为char类型,在.c文件中的int都要一一替换成char
typedef struct SeqList
{
SLDataType* arr;
int size;//有效数据个数
int capacity;//空间大小
}SL;
//顺序表的初始化
void SLInit(SL* ps);
//顺序表的销毁
void SLDestroy(SL* ps);
//顺序表的打印
void SLPrint(SL s);
//头部插入删除/尾部插入删除
void SLPushBack(SL* ps, SLDataType x);
void SLPushFront(SL* ps, SLDataType x);
void SLPopBack(SL* ps);
void SLPopFront(SL* ps);
//在指定位置之前插入/删除数据
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);
int SLFind(SL* ps, SLDataType x);
源文件
实现顺序表的方法
//顺序表初始化
void SLInit(SL* ps)
{
ps->arr = NULL;
ps->size = ps->capacity = 0;
}
//顺序表都销毁
void SLDestroy(SL* ps)
{
if (ps->arr)
{
free(ps->arr);
}
ps->arr = NULL;
ps->size = ps->capacity = 0;
}
//顺序表打印
void SLPrint(SL s)
{
for (int i = 0; i < s.size; i++)
{
printf("%d", s.arr[i]);
}
printf("\n");
}
//检查空间是否足够
void checkcapacity(SL* ps)
{
if (ps->capacity == ps->size)
{
//申请空间
//malloc calloc realloc int arr[100] 增容realloc
int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
SLDataType* tmp = ps->arr = (SLDataType*)realloc(ps->arr, ps->capacity * 2 * sizeof(SLDataType));
if (tmp == NULL)
{
perror("realloc fail");
exit(1);//直接退出程序
}
ps->arr = tmp;
ps->capacity = newCapacity;
}
}
//尾插
void SLPushBack(SL* ps, SLDataType x)
{ //法一
/*if (ps == NULL)
{
return;
}*/
//法二
assert(ps);//等价于assert(ps != NULL)
checkcapacity(ps);
ps->arr[ps->size++] = x;
//ps->arr[ps->size] = x;
//++ps->size;
}
//头插
void SLPushFront(SL* ps, SLDataType x)
{
assert(ps);
checkcapacity(ps);
//先让已有数据后移一位
for (int i = ps->size; i > 0; i--)
{
ps->arr[i] = ps->arr[i - 1];//arr[1] = arr[0]
}
ps->arr[0] = x;
ps->size++;
}
//尾删
void SLPopBack(SL* ps)
{
assert(ps);
assert(ps->size);
//顺序表不为空
//ps->arr[ps->size - 1] - 1;
ps->size--;
}
//头删
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];
}
ps->size--;
}
//在指定位置之前插入数据
void SLInsert(SL* ps, int pos, SLDataType x)
{
assert(ps);
assert(pos >= 0 && pos < ps->size);
//插入数据,空间够不够
checkcapacity(ps);
for (int i = ps->size; i>pos; i--)
{
ps->arr[i] = ps->arr[i - 1];//arr[pos+1] = arr[pos]
}
ps->arr[pos] = x;
ps->size++;
}
//删除指定位置前的数据
void SLErase(SL* ps, int pos)
{
assert(ps);
assert(pos >= 0 && pos < ps->size);
for (int i = pos; i < ps->size; i++)
{
ps->arr[i] = ps->arr[i + 1];
}
ps->size--;
}
//查找
int SLFind(SL* ps, SLDataType x)
{
assert(ps);
for (int i = 0; i < ps->size; i++)
{
if (ps->arr[i] == x)
{
return i;
}
}
return -1;
}