线性表(linear list)
线性表是具有相同数据元素的有限序列,常见的线性表有:顺序表、链表、栈、队列、字符串等,线性表是一种逻辑结构,也就是说地址也许不是连续的,但是却能通过上一个元素找到下一个元素。
优点:线性表的逻辑结构简单,便于实现和操作。因此,线性表这种数据结构在实际应用中是广泛采用的一种数据结构
接下来我们细细学习线性表中的顺序表与链表
顺序表
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构。
顺序表一般分为:1、静态顺序表:使用定长数组存储元素(可以理解为我们平时使用的有固定元素个数的数组)
2、动态顺序表:使用动态开辟的空间存储元素
在使用中,静态顺序表因为其在使用前就得固定大小,那么就导致了使用者在创建表之前就得知道自己需要的大小,而很多情况下我们是无法事先预料的,那么就导致了要么开辟小了,要么开辟多了造成浪费,所以我们更多使用动态顺序表,这样对空间的才会有更好的使用,下面我们来一起看看动态顺序表的增删查改
#define S_CAPCITY 5
typedef int SLDataType;
// 顺序表的动态存储
typedef struct SeqList
{
SLDataType* array; // 指向动态开辟的数组
size_t size ; // 有效数据个数
size_t capicity ; // 容量空间的大小
}SeqList;
// 基本增删查改接口
// 顺序表初始化
void SeqListInit(SeqList* psl);
// 检查空间,如果满了,进行增容
void CheckCapacity(SeqList* psl);
// 顺序表尾插
void SeqListPushBack(SeqList* psl, SLDataType x);
// 顺序表尾删
void SeqListPopBack(SeqList* psl);
// 顺序表头插
void SeqListPushFront(SeqList* psl, SLDataType x);
// 顺序表头删
void SeqListPopFront(SeqList* psl);
// 顺序表查找
int SeqListFind(SeqList* psl, SLDataType x);
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* psl, size_t pos);
// 顺序表销毁
void SeqListDestory(SeqList* psl);
// 顺序表打印
void SeqListPrint(SeqList* psl);
顺序表的初始化
void SeqListInit(SeqList* psl)
{
assert(psl);
psl->arry=(SLDataType*)malloc(sizeof(SLDataType)*S_CAPCITY);
//初始化后一定要对初始化空间创建是否成功进行判断
if(psl->NULL)
{
perror("SeqListInit::malloc");
}
psl->sizeof=0;
psl->capcity=S_CAPCITY;
}
//检查空间,满了之后就增容
void CheckCapacity(SeqList* psl)
{
assert(psl);
if(psl->sizeof==psl->capcity)
{
SeqList*Tmp=(SeqList*)realloc(psl,sizeof(SeqList)*(psl->capcity)*2);
if(psl==NULL)
{
perror("CheckCapcity::realloc");
return;
}
//创建完扩容空间后要将realloc的空间指针赋值给psl->array
psl->array=Tmp;
psl->capcity=capcity*2;
}
}
// 顺序表尾插
void SeqListPushBack(SeqList* psl, SLDataType x)
{
assert(psl);
CheckCapacity(psl);
//psl->array[psl->size]=x;
//psl->size+=1;
psl->array[psl->size++]=x;
}
// 顺序表尾删
void SeqListPopBack(SeqList* psl)
{
assert(psl);
//psl->array[size]=0;
//psl->size--;
psl->array[size--]=0;
}
// 顺序表头插
void SeqListPushFront(SeqList* psl, SLDataType x)
{
assert(psl);
CheckCapacity(psl);
int num=psl->size-1;//要防止越界的情况发生
while(num>=0)
{
psl->array[num+1]=psl->array[num];
num--;
}
psl->array[0]=x;
psl->size++;
}
// 顺序表头删
void SeqListPopFront(SeqList* psl)
{
assert(psl);
int num=0;
while(num<psl->size)
{
psl->array[num]=psl->array[num+1];
num++;
}
psl->size--;
}
// 顺序表查找
int SeqListFind(SeqList* psl, SLDataType x)
{
assert(psl);
int num=0;
while(num<psl->size)
{
if(psl->array[num]==x)
{
return x;
}
num++;
}
return -1;
}
// 顺序表在pos位置插入x
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x)
{
assert(psl);
// 还要判断要插入的位置是否是在正确区域内
assert(pos>=0&&pos<psl->size);
CheckCapacity(psl);//判断是否足够空间去增加这个值
int num=psl->size-1;//找到最后一值的位置,从这个值开始逐次向后,直至pos位
while(num>=pos)
{
psl->array[num+1]=psl->array[num];
num--;
}
psl->array[pos]=x;
psl->size++;
}
// 顺序表删除pos位置的值
void SeqListErase(SeqList* psl, size_t pos)
{
assert(psl);
//仍要判断要删除的位置是否合理
assert(pos>=0&&pos<psl->size);
int n=pos;
while(n<psl->size-1)
{
psl->array[n]=psl->array[n+1];
}
psl->size--;
}
// 顺序表销毁
void SeqListDestory(SeqList* psl)
{
//判断是否为空
assert(psl);
free(psl->array);
psl->array=NULL;
psl->size=psl->capcity=0;
}
// 顺序表打印
void SeqListPrint(SeqList* psl)
{
assert(psl);
int num=psl->size;
while(num--)
{
print("%d",psl->arrary[num]);
}
}