文章目录
1.单链表概念
链表是由一个一个的节点(结点)组成的
一个节点有两个部分组成,要存储的数据+指针(结构体指针)
2.节点的结构
typedef int SLDataType;
typedef struct SListNode{
SLDataType data;
struct ListNode *next;
}SLNode;```
申请空间:#include<stdlib.h>
不存在扩容:malloc
3.链表的打印
3.1 链表申请节点
void BuyNode(SLNode **pphead,SLDataType x){
while(ptail->next==NULL){
SLNode *newnode=(SLNode*)malloc(sizeof(SLNode));
if(patil->next==newnode){
printf("malloc failed");
exit(-1);
}
}
}
3.2链表的尾插
对一级指针取地址,必须用二级指针来接受一级指针的地址
void PushBack(SLNode**pphead,SLDataType x){
assert(pphead);
SLNode *newnode=BuyNode(x);
//链表为空,新节点作为pphead
if(*pphead==NULL){
*pphead=newnode;
return ;
}
//链表不为空
SLNode*ptail=*pphead;
while(ptail->next){
ptail=ptail->next;
}
patil->next=newnode;
}
3.3链表的头插
3.4链表的尾删
void PopBack(ListNode**pphead){
assert(pphead);
assert(*pphead);
if((*pphead)->next==NULL){
free(*pphead);
*pphead=NULL;
}
ListNode *prev=NULL;
ListNode*ptail=*pphead;
while(ptail->next){
prev=ptail;
ptail=ptail->next;
}
prev->next=NULL;
//销毁尾节点
free(ptail);
ptail=NULL;
}
3.5链表的头删
void PopFront(ListNode**pphead){
assert(pphead);
assert(*pphead);//链表不能为空
ListNode *cur=*pphead;//让第二个节点成为新的头
*pphead=(*pphead)->next;//将旧的头释放掉
free(cur);
}
3.6链表的查找
LNode* FindLNode(LNode **pphead,SLDataType x){
assert(pphead);
LNode *pcur=*pphead;
while(pcur){
if(pcur->data==x){
return pcur;
}
pcur=pcur->next;
}//没有找到
return NULL;
}
3.7在指定位置之前插入数据
void Insert(LNode*pphead,LNode* pos,SLDataType x){
assert(pphead);
assert(pos);
LNode*newnode=BuyNode(x);
if(pos==*pphead){
PushFront(pphead,x);
return ;
}
LNode*prev=*pphead;
while(prev->next!=pos){
prev=prev->next;
}
prev->next=newnode;
newnode->next=pos;
}
3.8在指定位置之后插入数据
void InsertAfter(LNode* pos,SLDataType x){
assert(pphead);
assert(pos);
LNode*newnode=BuyNode(x);
LNode*ptail=*pphead;
newnode->next=ptail;
pos->next=newnode;
}
3.9删除pos节点
void LErase(LNode*pphead,LNode* pos){
assert(pphead);
assert(*pphead);
assert(pos);
if(pos==*pphead){
PopFront(pphead);
return;
}
LNode*prev=*pphead;
while(prev->next!=pos){
prev=prev->next;
}
prev->next=pos->next;
free(pos);
pos=NULL;
}
3.10删除pos之后的节点
void EraseAfterPos(LNode*pphead,LNode* pos){
assert(pos);
asssert(pos->next);
LNode*del=pos->next;
pos->next=pos->next->next;
free(del);
del=NULL;
}
3.11链表的销毁
void Destory(LNode*pphead){
assert(pphead);
assert(*pphead);
LNode*pcur=*pphead;
while(pcur){
SLNode* next=pcur->next;
free(pcur);
pcur=next;
}
*pphead=NULL;
}
4.链表的结构
单链表:不带头单向不循环链表
一共有8种链表
单链表中提到的“头节点”是第一个有效的节点
带头结点的“头”是无效的节点
虽然链表的种类非常之多,但是使用比较多的只有两种:单链表(不带头单向不循环链表)和双向链表(带头双向循环链表)