数据结构-1.4链表(反转链表)

本文探讨了链表操作,包括在头节点处进行反转和插入。详细提供了两种情况的全部代码,一种是在头节点处反转链表,另一种是在任意位置插入后再反转。文章附带了相应的运行结果,展示操作的实现效果。
摘要由CSDN通过智能技术生成

 在头节点插入再反转

这部分代码是直接从头节点处采用首插法

全部代码

#include<stdio.h>
#include<stdlib.h>
/*
功能:反转链表(我们只是调整链接,节点的地址不变)
实现:通过遍历整个链表,来调整链接部分,使它指向上一个节点,而不是下一个节点
如果没有前一个节点,我们认为前一个节点为NULL;最后遍历到最后,把头指针放在最后
链表为空,或者链表只有一个节点这段代码都是可以实现的
*/
struct Node {
	int date;
	struct Node* next;
};

//写一个反转函数
/*
这里我们接受头节点的地址作为参数,然后在链表反转后,返回头节点的地址
*/
struct Node* Reverse(struct Node*head) {

	struct Node* PrevNode=NULL;//上一个节点
	struct Node* CurrentNode;//当前节点
	CurrentNode = head;
	struct Node* NextNode;//下一个节点

	//遍历,因为我们在遍历的时候只能知道下一个节点,所以需要一个变量来存储上一个节点,还需要知道当前节点
	while (CurrentNode != NULL) {
		NextNode = CurrentNode->next;//首先把下一个节点信息(CurrentNode->next)存储在NextNode中
		CurrentNode->next = PrevNode;//把当前节点的连接部分(CurrentNode->next)指向前一个节点(PrevNode)
		
		PrevNode = CurrentNode;//上一个节点信息进行移动到当前节点
		CurrentNode = NextNode;//当前节点移动到下一个节点
	}

	head = PrevNode;//此时,CurrentNode和NextNode都指向空,而PrevNode指向最后一个结点
	return head;
}
struct Node* Insert(int x, struct Node*head)//插入这里我们需要地址传递
{
	//定义一个临时变量来进行插入
	struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
	temp->date = x;
	temp->next = NULL;


	//接下来就是我们每次创建一个节点,都要进行插入,每次要把新创建的temp的地址给头指针,并且还有把头指针存储的下个节点的地址给temp的地址域
	if (head != NULL) temp->next = head;//(这里是把首节点的地址给temp)

	//接下来把temp的地址给head
	head = temp;
	return head;
}
void Print(struct Node* head)//这时需要传入头节点的值,是值传递
{

	printf("链表是:");
	while (head != NULL)
	{
		printf(" %d", head->date);
		head = head->next;//这种方法对节点进行遍历
	}
	printf("\n");

}
int main(void) {
	struct Node* head=NULL;//head作为了局部变量,head为全局变量的话反转函数就不是struct类型的了,而是空类型的 void
	head = Insert(1, head);
	head = Insert(5, head);
	head = Insert(4, head);
	head = Insert(7, head);

	//打印链表
	Print(head);
	head = Reverse(head);
	Print(head);
	return 0;
}

运行结果

 在任意位置插入再反转

这里的代码会更复杂一些,但是原理和之前的代码差不多,最后把相关信息打印

 代码

#include<stdio.h>
#include<stdlib.h>
struct Node {
	int date;
	struct Node* next;
};
struct Node* Insert(struct Node* head, int x,int n) {

	struct Node* temp=(struct Node*)malloc(sizeof(struct Node));
	temp->date = x;
	temp->next = NULL;
	if (n == 1) {
	//这里是头插法
		temp->next = head;
		head = temp;
		printf("在头指针head插入,插入数据为:%d\n", head->date);
		return  head;
	}

	struct Node* listread=head;
	for (int i = 0; i < n-2; i++)//这是遍历到了n-1个节点
	{
		listread = listread->next;
	}
	temp->next = listread->next;
	listread->next = temp;
	printf("在节点%d处插入,插入值为%d\n", n, temp->date);
	return head;
}
void Print(struct Node* head) {
	struct Node* Readlist;
	Readlist = head;
	printf("链表的信息为:");
	while (Readlist != NULL) {
		printf("%d ", Readlist->date);//打印的代码一定要写在遍历代码的前面
		Readlist = Readlist->next;
	}
	printf("\n");
}
struct Node* Reverse(struct Node* head) {

	struct Node* pre, * current, * next;
	pre = NULL;
	next = NULL;
	current = head;

	while (current != NULL) {
	/*
	这段代码的逻辑并不是简单的遍历
	第一步:我们需要先保存下一个节点的地址
	第二步:把当前节点.next指向前一个节点,进行反转
	第三步:各个节点开始向后移动
	*/
		 next= current->next;
		current->next = pre;//这一步就先反转

		//各个节点开始移动(移动方法,上一个节点移向当前节点;当前节点移动到下一个节点)
		pre = current;
		current = next;
	}

	//跳出循环的时候,current=NULL,next=NULL,这时刚好头指针指向pre
	head = pre;
	return head;
}
int main(void) {
	struct Node* head=NULL;
	head=Insert(head, 1, 1);
	Print(head);
	head = Insert(head, 3, 2);
	Print(head);
	head = Insert(head, 5, 1);
	Print(head);
	head = Insert(head, 4,2);
	Print(head);
	head=Reverse(head);
	Print(head);
	return 0;

}

 运行结果

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

编程者也

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

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

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

打赏作者

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

抵扣说明:

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

余额充值