目录
目录
一,线性表
线性表是n个具有相同特性的数据元素的有限序列,常见有:顺序表,栈,队列,字符串等
线性表在逻辑上是线性结构,连续的,但在物理结构上不一定连续。线性表在物理上存储时,通常以数组和链式结构的形式存储。
二,顺序表
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
静态顺顺序表:使用定长数组存储元素。
#define N 7
typedef int SLDateType;
typedef struct SeqList
{
SLDateType arr[N]; //定长数组
size_t size; //有效数据的个数
}SeqList;
//效率低,浪费空间
动态顺序表:使用动态开辟的数组存储。
//顺序表的动态存储
typedef int SLDateType;
typedef struct SeqList
{
SLDateType* a; //定长数组
size_t size; //有效数据的个数
size_t capicity; //容量空间的大小
}SeqList;
//空间不够可以扩容
三, 动态顺序表的增删查改
动态顺序表有如下接口:
#define Init_capicity 7 //初始容量
typedef int SLDataType;
typedef struct SeqList
{
SLDataType* a; //存放数据
int size; //数据的下标
int capicity; //数据的容量
}SeqList;
void Seq_Init(SeqList* ps); //顺序表的初始化
void Seq_Destory(SeqList* ps); //顺序表的销毁
void Seq_PushBack(SeqList* ps,SLDataType x); //尾插
void Seq_PopBack(SeqList* ps); //尾删
void Seq_PushFront(SeqList* ps,SLDataType x); //头插
void Seq_PopFront(SeqList* ps); //头删
void Seq_Print(SeqList* ps); //打印
void CheckCapacity(SeqList* ps); //检查空间
int Seq_Find(SeqList* ps,SLDataType x); //查找
void Seq_Insert(SeqList* ps, int pos, SLDataType x);//在pos位置插入x
void Seq_Erase(SeqList* ps, int pos);//删除pos位置的值
四,接口实现
4.1.顺序表的初始化:
void Seq_Init(SeqList* ps) //顺序表的初始化
{
ps->a = (SLDataType*)malloc(Init_capicity*sizeof(SLDataType));//malloc(字节数)
if (ps->a == NULL)
{
perror("malloc fail");
return;
}
ps->size = 0;
ps->capicity = Init_capicity;
}
perror:
void perror ( const char * str ); //头文件是 stdio.h
将 errno 的值解释为错误消息,并将其打印到 stderr(标准错误输出流,通常是控制台),可以选择在其前面加上 str 中指定的自定义消息。
errno 是一个整数变量,其值描述调用库函数生成的错误条件或诊断信息(C 标准库的任何函数都可以为 errno 设置值,即使未在此参考中显式指定,即使未发生错误),有关详细信息,请参阅 errno。
错误生成的错误消息取决于平台。
如果参数 str 不是空指针,则打印 str 后跟冒号 (:)和一个空间。然后,无论 str 是否为空指针,都会打印生成的错误描述,后跟换行符 ('\n')。
4.2 顺序表的销毁:
void Seq_Destory(SeqList* ps) //顺序表的销毁
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capicity = ps->size = 0;
}
用断言的好处 :出现错误控制台会告诉错误位置。
4.3 顺序表的打印
void Seq_Print(SeqList* ps) //打印
{
assert(ps);
for (int i = 0; i < ps->size; i++)
{
printf("%d ", ps->a[i]);
}
printf("\n");
}
4.4 顺序表的空间检查:
比较下标是否与容量相同,相同用realloc扩容。
void CheckCapacity(SeqList* ps) //检查空间
{
assert(ps);
if (ps->size == ps->capicity) //可用空间没有扩容
{
SLDataType* tmp = (SLDataType*)realloc(ps->a, (sizeof(SLDataType)) * ps->capicity * 2);
if (tmp == NULL)
{
perror("realloc fail");
return 0;
}
ps->a = tmp;
ps->capicity *= 2;
}
}
4.5 顺序表的打印:
void Seq_Print(SeqList* ps) //打印
{
assert(ps);
for (int i = 0; i < ps->size; i++)
{
printf("%d ", ps->a[i]);
}
printf("\n");
}
4.6 顺序表的尾部插入:
在最后面创建一个空间,直接在后面插入数据。
void Seq_PushBack(SeqList* ps, SLDataType x) //尾插
{
assert(ps);
CheckCapacity(ps);
ps->a[ps->size++] = x;
}
4.7 顺序表的尾部删除:
直接将下标减一。
void Seq_PopBack(SeqList* ps) //尾删
{
assert(ps);
if (ps->size == 0)
{
return;
}
ps->size--;
}
4.8 顺序表的头部插入:
在后面创建一个空间,将前一位移至后一位。直到第一位的数据也被移到后一位。
void Seq_PopBack(SeqList* ps) //尾删
{
assert(ps);
if (ps->size == 0)
{
return;
}
ps->size--;
}
4.9 顺序表的头删:
从前面开始,将后面一位赋值该前一位。最后将下标减一。
void Seq_PopFront(SeqList* ps) //头删
{
assert(ps);
int begin = 0;
while (begin < ps->size)
{
ps->a[begin] = ps->a[begin + 1];
begin++;
}
ps->size--;
}
4.10 顺序表的查找:
int Seq_Find(SeqList* ps, SLDataType x) //查找
{
assert(ps);
for (int i = 0; i < ps->size; i++)
{
if (ps->a[i] == x)
{
return i; //返回下标值
}
}
return -1;
}
4.11 在pos位置插入x:
在顺序表最后创建一个空间,从最后开始,将前一位赋值到后一位,直到前一位小于pos停止。
void Seq_Insert(SeqList* ps, int pos, SLDataType x)//在pos(下标处)位置插入x
{
assert(ps);
assert(0 <= pos && pos <= ps->size);
CheckCapacity(ps);
int end = ps->size - 1;
while (end >= pos)
{
ps->a[end + 1] = ps->a[end];
end--;
}
ps->a[pos] = x;
ps->size++;
}
4. 12 删除pos位置的值:
从pos的位置开始,将后一位赋值到前一位,直到后一位是最后一位停止。
void Seq_Erase(SeqList* ps, int pos)//删除pos位置的值
{
assert(ps);
assert(0 <= pos && pos <= ps->size);
SLDataType i = pos;
while (i < ps->size)
{
ps->a[i-1] = ps->a[i];
i++;
}
ps->size--;
}
可以用后两个代替头插,头删,尾插,尾删:
void Seq_PushBack(SeqList* ps, SLDataType x) //尾插
{
//assert(ps);
//CheckCapacity(ps);
//ps->a[ps->size++] = x;
Seq_Insert(ps, ps->size, x);
}
void Seq_PopBack(SeqList* ps) //尾删
{
//assert(ps);
//if (ps->size == 0)
//{
// return;
//}
//ps->size--;
Seq_Erase(ps, ps->size);
}
void Seq_PushFront(SeqList* ps, SLDataType x) //头插
{
//assert(ps);
//int end = ps->size - 1;
//while (end >= 0)
//{
// ps->a[end + 1] = ps->a[end];
// --end;
//}
//ps->a[0] = x;
//ps->size++;
Seq_Insert(ps, 0, x);
}
void Seq_PopFront(SeqList* ps) //头删
{
//assert(ps);
//int begin = 0;
//while (begin < ps->size)
//{
// ps->a[begin] = ps->a[begin + 1];
// begin++;
//}
//ps->size--;
Seq_Erase(ps, 0);
}
所以源代码见gitee:初阶数据结构/SeqList1 · 雨天code/CSDN1 - 码云 - 开源中国 (gitee.com)