顺序表的缺陷:
1.如果空间不够,增容。增容会付出一定性能销毁,其次可能存在一定的空间浪费。(开辟的空间可能没有完全利用完)
2.顺序表在物理空间上是连续的,导致了内存的利用效率不高。
3.头部或者中部左右的插入删除效率低->o(n);
链表的特点:
空间上,按需给空间。不要求物理空间连续,头部和中间插入,不需要挪动数据。
概率:链表是一种物理存储结构上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
缺点:存储数据方便,但是访问数据时复杂
单链表
1.单链表逻辑结构和物理结构![](https://img-blog.csdnimg.cn/16e431f3ca204dae994f89015f604e5b.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5b2x5Lit5Lq6bHg=,size_20,color_FFFFFF,t_70,g_se,x_16)
链表的物理空间在内存中是不要求连续的
2.宏定义
typedef int SLDataType; //存储的数据类型
struct SListNode
{
SLDataType data;
struct SListNode*next //下一个元素的指针
};
typedef struct SListNode SLTNode;
3.单链表的实现
打印接口
void SListPrint(SLTNode* phead)
{
SLTNode*cur=phead;
while(cur!=NULL)
{
printf("%d",cur->data);
cur=cur->next;
}
}
尾插接口
void SListPushback(SLTNode** pphead,SLTDataType x)
{
SLTNode*newnode=(SLTNode*)malloc(sizeof(SLTNode));
newnode->data=x;
newnode->next=NULL;
if(*pphead==NULL)
{
*pphead=newnode;
}
else
{
SLTNode*tail=*pphead;
//结束条件为tail->next==NULL;
while(tail->next!=NULL)
{
tail=tail->next;
}
tail->next=newnode;
}
}
头插函数
void SListPushFront(SLTNode** pphead,SLTDataType x)
{
SLTNode*newnode=(SLTNode*)malloc(sizeof(SLTNode));
newnode->data=x;
newnode->next=*pphead;
*pphead=newnode;
}
头删接口
void SListPopFront(SLTNode** pphead)
{
SLTNode*next=(*pphead)->next;
free(*pphead);
*pphead=next;
}
尾删接口
void SListPopback(SLTNode** pphead)
{
assert(*pphead);
SLTNode*prev=NULL;
SLTNode*tail=*pphead;
if(*pphead->next=NULL)
{
free(*pphead);
*pphead=NULL;
}
else
{
while(tail->next!=NULL)
{
prev=tail;
tail=tail->next;
}
free(tail);
prev->next=NULL;
}
}
查找接口
SLTNode* SListFind(SLTNode*phead,SLTDataType x)
{
SLTNode*cur=phead;
while(cur)
{
if(cur->data==x)
{
return cur
}
cur=cur->next;
}
return NULL;
}
随机插入接口
void SListInsert(SLTNode** pphead,SLTNode*pos,SLTDataType x)
{
SLTNode*prev=*pphead;
if(prev==pos)
{
SListPushFront(pphead,x);
}
else
{
SLTNode*newnode=(SLTNode*)malloc(sizeof(SLTNode));
while(prev->next!=pos)
{
prev=prev->next;
}
prev->next=newcode;
newcode->next=pos;
newcode->data=x;
}
}
随机删除接口
void SListErase(SLTNode** pphead,SLTNode*pos)
{
assert(pos);
SLTNode*prev=*pphead;
if(prev==pos)
{
SListPopback(pphead);
}
else
{
while(prev->next!=pos)
{
prev=prev->next;
}
prev->next=pos->next;
free(pos);
}
}