单向链表(各种操作合集)
单向链表的两种创建方式
方式1:根据函数的返回值创建
- 通过
返回值
返回所申请的头结点所在的内存空间首地址
,即创建单向链表的头结点,代码如下:
- 示例代码:
node_t *create_link_node_1(){
node_t *phead = (node_t *)malloc(sizeof(node_t));
if(NULL == phead){
printf("内存分配失败\n");
exit(-1);
}
phead->data = -1;
phead->next = NULL;
return phead;
}
- 注意事项:
- 1.分配完头结点的内存地址空间后,一定要检查
内存分配是否成功
;
- 2.若头结点的内存分配失败,需要使用
shell命令exit(-1)退出
;
- 3.单向链表的
每个结点都有数据域和指针域
,而头结点的数据域可以不储存任何数据
,头结点的数据域
在此函数中,被赋值 -1
;
- 4.头结点的
指针域被赋值 NULL
,表示此时的单向链表只有一个头结点
;
方式2:根据地址传参创建
- 使用
地址传参
的方式创建单向链表的头结点,代码如下:
- 示例代码:
int create_link_node_2(node_t **phead,int data){
if(NULL == phead){
printf("入参为NULL\n");
return -1;
}
*phead = (node_t *)malloc(sizeof(node_t));
if(NULL == *phead){
printf("内存分配失败\n");
return -1;
}
(*phead)->data = data;
(*phead)->next = NULL;
return 0;
}
注意事项:
- 1.所传入的形参必须是
二级指针变量
,因为二级指针用来存储一级指针变量的地址
,即所申请的单向链表头结点在内存空间的地址
;
- 2.形参传入到创建单向链表头结点的功能函数后,一定要做
入参合理性检查
;
- 3.同方式1一样,分配完头结点的内存地址空间后,一定要检查
内存分配是否成功
;
- 4.头结点的
数据域被赋值 -1
;
- 5.头结点的
指针域被赋值 NULL
;
单向链表的三种插入方式
方式1:头插法
- 在单向链表的
头结点和第0个结点之间
插入新结点,即头插法
,代码如下:
- 示例代码:
int insert_link_list_1(node_t *phead,int data){
if(NULL == phead){
printf("入参为NULL\n");
return -1;
}
node_t *pnew = NULL;
create_link_node_2(&pnew,data);
pnew->next = phead->next;
phead->next = pnew;
return 0;
}
- 操作步骤:
- 1.创建新结点
pnew
;
- 2.将第0个结点的地址指向新结点的指针域,即
pnew->next = phead->next
;
- 3.再将新结点的地址指向头结点的指针域,即
phead->next = pnew
;
方式2:尾插法
- 在单向链表的
最后一个结点后面插入新结点
,即尾插法
,代码如下:
- 示例代码:
int insert_link_list_2(node_t *phead,int data){
if(NULL == phead){
printf("入参为NULL\n");
return -1;
}
node_t *pnew = NULL;
create_link_node_2(&pnew,data);
node_t *ptemp = phead;
while(NULL != ptemp->next){
ptemp = ptemp->next;
}
ptemp->next = pnew;
return 0;
}
- 操作步骤:
- 1.创建新结点
pnew
;
- 2.遍历链表,找到链表的最后一个结点
ptemp
;
- 3.将新结点的地址指向最后一个结点的指针域,即
ptemp->next = pnew
;
方式3:任意位置插入新节点
- 在单向链表的任意一个位置,插入新结点,代码如下:
- 示例代码:
int insert_link_list_3(node_t *phead,int pos,int data