关于《链表》(单向链表的简单操作·下)

本文详细介绍了单向链表的插入、删除以及交换操作,包括如何在链表中插入新节点,删除重复结点,以及交换指定节点的值。通过示例代码展示了这些操作的过程和应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

承接上篇,本篇介绍单向链表的另外三种简单操作。

目录

1·链表的插入

2·链表的删除

3·链表的交换


1·链表的插入

 

若要将r指向的数据项插入到p0和p指向的数据项之间 ,则使p0指向的指针部分指向r指向的数据部分,使r指向的指针部分指向p指向的数据部分。

则有操作: 

r->next=p;
p0->next=r;
p0=r;
2·链表的删除

 在如上链表中,若要删除p所指的数据项,则有如下操作:

p = p->next;//指向下一项
free(p0->next);//删除掉p原先所指的一项
p0->next = p;

下面参考一道完整例题

题目名称:删除单链表重复结点

题目描述:首先根据键盘随机输入,以0结束的若干非零整数建立单链表;然后删除此链表中值重复的结点仅保留一个,且不改变原有结点顺序;最后将删除后链表中各结点值输出,相邻数字间以一个西文空格间隔,最后一个数字后无任何字符;若是空链表,则输出NULL。

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
#include<malloc.h>
struct cell {
	int x;
	struct cell* next;
};//单链表结构体定义
struct cell* build(void) {
	struct cell* head, * tmp, * p;
	head = tmp = p = NULL;
	int n;
	head = (struct cell*)malloc(sizeof(struct cell));
	scanf("%d", &head->x);
	tmp = head;
	tmp->next = NULL;
	if (head->x == 0)head = NULL;
	else {
		do {
			p = (struct cell*)malloc(sizeof(struct cell));
			scanf("%d", &p->x);
			tmp->next = p;
			tmp = p;
			tmp->next = NULL;
		} while (p->x != 0);
	}
	return head;
}//新建链表并将建好的单链表首地址返回
struct cell* del2one(struct cell* head) {
	struct cell* p, * q, * r;
	p = head;
	while (p != NULL) {
		q = p;
		while (q->next != NULL) {
			if (q->next->x == p->x) {
				r = q->next;
				q->next = r->next;
			}
			else {
				q = q->next;
			}
		}
		p = p->next;
	}//在p遍历的起始,用q先代替p遍历一遍,如果有与p重复的节点,删除该节点;若没有,则继续遍历
	return head;
}//删除重复节点只保留一个
void print(struct cell* head) {
	struct cell* p;
	printf("%d", head->x);
	p = head->next;
	while (p->x != NULL) {
		printf(" %d", p->x);
		p = p->next;
	}
}
void release(struct cell* head) {
	struct cell* p;
	while (head != NULL) {
		p = head;
		head = p->next;
		free(p);
	}
}
int main(void) {
	struct cell* head;
	head = build();
	head = del2one(head);
	if (head != NULL)
		print(head);
	else
		printf("NULL");
	release(head);
}
3·链表的交换

若要将p所指的项与q所指的项交换,最简单的方法是把p所指的项与q所指的项中的基本数据部分交换。但如果数据量过大,则会浪费时间。那么,我们通过修改指针来交换单向链表上的两项:

/*第一步交换p->next、q->next*/
g = p->next;
p->next = q->next;
q->next = g;
/*第二步交换p0->next、q0->next*/
p0->next = q;
q0->next = p;
/*第三步为非必要操作,交换指针p、q*/
p = p0->next;
q = q0->next;

下面来看完整的例题:题目名称:排序单链表

题目描述:

    首先根据键盘随机输入一行以0结束的若干非零整数建立单链表;

    然后递增排序链表;

    最后验证输出排序后链表中所有值,相邻数字间以一个西文空格间隔,最后一个数字后无任何字符。

    若是空链表,则输出NULL。

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
#include<malloc.h>
struct cell {
	int x;
	struct cell* next;
};
struct cell* build(void) {
	struct cell* head, * tmp, * tail;
	head = tmp = tail = NULL;
	int n;
	scanf("%d", &n);
	if (n == 0)
		return NULL;
	head = (struct cell*)malloc(sizeof(struct cell));
	head->x = n;
	head->next = NULL;
	tail = head;
	while (1)
	{
		scanf("%d", &n);
		if (n == 0)
			return head;
		tmp = (struct cell*)malloc(sizeof(struct cell));
		tmp->x = n;
		tmp->next = NULL;
		tail->next = tmp;
		tail = tail->next;
	}
	return head;
}
struct cell* sort(struct cell* head) {
	struct cell* p, * p0, * r, * r0, * q;
	p = p0 = r = r0 = q = NULL;
	p = head;
	while (p != NULL) {
		r = head;
		while ((r->x < p->x) && (r != p))
		{
			r0 = r;
			r = r->next;
		}
		if (r != p) {
			q = p;
			p0->next = p->next;
			p = p0;
			if (r == head) {
				q->next = head;
				head = q;
			}
			else {
				q->next = r;
				r0->next = q;
			}
		}
		p0 = p;
		p = p->next;
	}
	return head;
}
void print(struct cell* head) {
	struct cell* p = head;
	int flag = 0;
	while (p != NULL) {
		if (flag)
			printf(" ");
		flag = 1;
		printf("%d", p->x);
		p = p->next;
	}
}
void release(struct cell* head) {
	struct cell* p = head, * tmp;
	while (p != NULL) {
		tmp = p;
		p = p->next;
		free(tmp);
	}
}
int main(void) {
	struct cell* head;
	head = build();
	if (head != NULL)
	{
		head = sort(head);
		print(head);
	}
	else
		printf("NULL");
	release(head);
}

 

至此,单向链表的基本操作介绍完毕,后续将会再做补充。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无须logic ᭄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值