单向链表存储c语言程序,C语言单链表的基本操作(附带源码)

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

2edb87e619229565d872161d8b18a837.gif

图 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

#include

#include

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

#include

#include

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>