C语言单链表的基本操作(附带源码)
对于单向链表常见的操作有链表结点数据的查找、插入和删除。

图 1:单向链表的插入和删除操作
C语言代码清单 1:在链表中查找、插入结点
运行结果为:
代码清单 2:在链表中删除结点
运行结果为:
声明:《C语言系列教程》为本站“54笨鸟”官方原创,由国家机构和地方版权局所签发的权威证书所保护。

图 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
声明:《C语言系列教程》为本站“54笨鸟”官方原创,由国家机构和地方版权局所签发的权威证书所保护。