2025年3月31日 星期一 乙巳(蛇)年 正月初一 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > C语言

C语言单链表的基本操作(附带源码)

时间:10-08来源:作者:点击数:66

对于单向链表常见的操作有链表结点数据的查找、插入和删除。

单向链表的插入和删除操作
图 1:单向链表的插入和删除操作
1) 单链表节点的查找

在单向链表中,查找目标数据,只需从 head 指向的表头结点出发,沿着链表顺序遍历整个链表,并一一比较各个结点数值域中的数据即可。例如,从 head 为头指针的单向链表中查找数值域中成员 data 为 x 的结点,可以编写成以下函数 find( ):

  • struct node{
  • int data;
  • struct node *next;
  • } *head;
  • void find(struct node *head, int x){
  • int i=1;
  • struct node *this; //定义一个当前结点指针
  • this = head; //当前结点从头结点开始查找
  • while((this != NULL) && !(this->data == x)){ //遍历链表
  • this = this->next; //不匹配,当前结点指针指向下一个结点
  • i++;
  • }
  • if(this==NULL)
  • printf("没有找到!\n");
  • else
  • printf("%d在链表的第%d个结点中!\n",x,i);
  • }
2) 单链表节点的插入

在数组的某个元素后面插入一个新的元素时,需要将该元素后面的所有元素都向后移动位置。而在链表的结点 p 后面插入一个新的结点,不必像数组那样移动后面的结点,只要将 p 的后继指针指向新的结点,并将新结点的后继指针指向 p 原来的后继结点即可(见图 1a) )。例如,在单向链表的 p 结点后面插入一个数值域成员 data 的值为 x 的新结点,可以编写成以下函数 ins( ):

  • void ins(struct node *p,int x){
  • struct node *new; //定义新结点
  • new = malloc(sizeof(struct node)); //为新结点申请内存空间
  • new->data = x; //给新结点数值域成员赋值
  • new->next = p->next; //新结点后继指针指向 p 的后继结点
  • p->next = new; //p 的后继结点指向新结点
  • }
3) 单链表节点的删除

在单向链表中,要删除指针 p 指向的结点,只要将其前面一个结点(前驱结点)的后继指针指向 p 后面的结点(后继结点),并释放 p 所占用的内存即可(见图 1b) )。例如,从 head 为头指针的单向链表中删除 p 指向结点,可以编写成以下函数 del( ):

  • void del(struct node *p){
  • struct node *this; //定义一个当前结点指针
  • this = head; //当前结点从头结点开始查找
  • if (this == p) //p 为头结点时
  • head = this->next;
  • else{
  • while(this->next !=p) // 遍历链表,查找 p 的前驱结点
  • this = this->next; //不匹配,当前结点指针指向下一个结点
  • this->next = p->next; //当前结点 this 的后继指针指向 p 的后继结点
  • }
  • free(p); //释放结点 p 占用的内存空间
  • }

完整示例+代码

1) 单链表节点的查找和插入

读入整数 n,建立一个单向链表,按顺序存储自然数 1 至 n,然后再在所有偶数后面插入 2。

C语言代码清单 1:在链表中查找、插入结点

  • #include <stdio.h>
  • #include <stdlib.h>
  • #include <malloc.h>
  • struct node{
  • int data;
  • struct node *next;
  • } *head, *q, *p;
  • void ins(struct node *p, int x)
  • {
  • struct node *new;
  • new = malloc(sizeof(struct node));
  • new -> data = x;
  • new -> next = p -> next;
  • p -> next = new;
  • }
  • void print( )
  • {
  • for(q = head; q != NULL; q = q -> next)
  • printf("%d ",q -> data);
  • printf("\n");
  • }
  • int main( )
  • {
  • int i,n;
  • printf("请输入一个正整数n:");
  • scanf("%d",&n);
  • head = malloc(sizeof(struct node)); //创建初始链表
  • head -> data = 1;
  • head -> next = NULL;
  • q = head;
  • for(i = 2; i <= n; i++){ //循环插入2~n
  • ins(q,i);
  • q = q -> next;
  • }
  • print();
  • for(q = head; q != NULL; q = q -> next){ //查找偶数并在后面插入2
  • if((q -> data) % 2 == 0){
  • ins(q,2);
  • q = q->next;
  • }
  • }
  • print();
  • system("pause");
  • return 0;
  • }

运行结果为:

请输入一个正整数n:8
1 2 3 4 5 6 7 8
1 2 2 3 4 2 5 6 2 7 8 2

2) 单链表节点的删除

读入整数 n,建立一个单向链表,按顺序存储自然数 1 至 n,然后删除其中所有的奇数。

代码清单 2:在链表中删除结点

  • #include <stdio.h>
  • #include <stdlib.h>
  • #include <malloc.h>
  • struct node{
  • int data;
  • struct node *next;
  • } *head, *q, *p;
  • void ins(struct node *p, int x)
  • {
  • struct node *new;
  • new = malloc(sizeof(struct node));
  • new -> data = x;
  • new -> next = p -> next;
  • p -> next = new;
  • }
  • void print( )
  • {
  • for(q = head; q != NULL; q = q -> next)
  • printf("%d ",q -> data);
  • printf("\n");
  • }
  • int main( )
  • {
  • int i,n;
  • printf("请输入一个正整数n:");
  • scanf("%d",&n);
  • head = malloc(sizeof(struct node)); //创建初始链表
  • head -> data = 1;
  • head -> next = NULL;
  • q = head;
  • for(i = 2; i <= n; i++){ //循环插入2~n
  • ins(q,i);
  • q = q -> next;
  • }
  • print();
  • q = head;
  • while(q -> next != NULL){ //查找并删除所有奇数
  • if((q -> data) % 2 == 1) {
  • q = head -> next;
  • free(head);
  • head = q;
  • }
  • else{
  • p = q -> next;
  • if((p -> data) % 2 == 1){
  • q -> next = p -> next;
  • free(p);
  • }
  • else
  • q = q -> next;
  • }
  • }
  • print();
  • system("pause");
  • return 0;
  • }

运行结果为:

请输入一个正整数n:8
1 2 3 4 5 6 7 8
2 4 6 8

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门