编程导航算法通关村第二关 | 终于学会链表反转了

青铜挑战-手写链表反转

链表翻转是一个出现率特别高的算法题,链表翻转是学习链表最重要的问题,没有之一
下面是来自LeetCode206:
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
在这里插入图片描述
解本题有两种方法,带头结点和不带头节点,重中之重,务必要搞懂

解法1. 建立虚拟头结点辅助反转链表

我们先建立一个虚拟头结点ans,这种方法其实就是对这个虚拟节点进行头插法把链表中的元素一个一个插进去,由于是头插法,所以先插进去的元素反而在后面,进而实现链表翻转,这种方法简单易懂,非常好理解,直接上代码:

ListNode* reverseList(ListNode* head) {
	// 建立虚拟头结点
	ListNode* ans = (ListNode*)malloc(sizeof(ListNode));
	ans->next = NULL;
	// 定义一个工作指针
	ListNode* p = head;
	// 遍历链表
	while(p != NULL) {
		ListNode* q = p->next;
		// 把当前元素用头插法插入ans
		p->next = ans->next;
		ans->next = p;
		// 更新工作指针
		p = q;
	}
	return ans->next;
}

这种方式好理解应用也广,但是万一遇到这种方法被禁止的情况怎么办?比如面试官想进一步考察你的能力,这个时候就要用到不带头节点的方法了


解法2. 直接操作链表实现翻转

先看一下下面这张链表翻转原理图
在这里插入图片描述
我们发现,链表翻转实质上就是翻转每个节点之间的指向,如果用p,q两个指针,我们可以做到让后一个指向前一个,如让2指向1:q->next = p,但是这样一来,2和3之间的链接就断了,导致我们永远都找不到3这个结点以及其后面的所有节点,所以我们再加入一个pre指针,使他成为p的前向结点,下面是执行示意图:

图中的prev对应pre,cur对应p,next对应q

在这里插入图片描述

ListNode* reverseList(ListNode* head) {
	// 前向指针初始时为空
	ListNode* pre = NULL;
	ListNode* p = head;
	// 遍历
	while(p != NULL) {
		ListNode* q = p->next;
		// 翻转两个节点的指向,让后一个结点指向前一个节点
		p->next = pre;
		// 更新指针,同时向后移
		pre = p;
		p = q;
	}
	return pre;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值