剑指offer代码解析——面试题16反转单链表

本题的详细解析均在代码中注释:

/**
 * 题目:将单链表反转,并输出反转后链表的头结点
 * @author 大闲人柴毛毛
 */
public class RevertLink {
	/**
	 * 分析:本题是要将链表“反转”,而不是反向输出,这点要特别注意。
	 * 反转需要改变链表的结构,使所有指针都指向相反方向;
	 * 而反向输出不需要改变链表结构,只需反向输出即可。
	 * 对于反向问题可使用栈来实现,可参见我的博客《剑指offer——面试题5》,这里不再赘述。
	 * 下面来解决反转问题。 
	 */
	
	/**
	 * 反转单链表其实就是将链表中的指针指向相反方向,
	 * 若a1和a2是单链表中两个相邻的结点,未反转前的状态是:a1.next = a2,
	 * 现在进行反转:a2.next = a1.
	 * 此时,虽然a2指向了a1,但链表出现了“断裂”,a2和它的后继结点发生了断裂,无法继续进行反转操作。
	 * 因此,我们需要再增加一个指针a3,指向a2的后继结点。
	 * 当反转完a2结点后,从a3开始继续依次向后进行反转操作,直到整个链表反转完为止。
	 * 代码如下:
	 */
	
	/**
	 * 反转链表
	 * @param first 链表的头结点
	 * @return 返回反转后链表的头结点
	 */
	public static <T> Node<T> revertLink(Node<T> first){
		//当链表为空时
		if(first==null){
			System.out.println("链表为空!");
			return null;
		}
		
		//当链表只有一个结点时
		if(first.next==null){
			return first;
		}
		
		//当链表只有两个结点时
		if(first.next.next==null){
			//end为链表的尾结点,是反转后的头结点
			Node<T> end = first.next;
			//将第二个结点的next域指向第一个结点
			first.next.next = first;
			//将第一个结点的next域设置null
			first.next = null;
			return end;
		}
		
		//当链表有三个及以上结点时
		{
			Node<T> a1 = first;//a1指向头结点
			Node<T> a2 = first.next;//a2指向第二个结点
			Node<T> a3 = first.next.next;//a3指向第三个结点
		
			//将头结点的后继设为null
			first.next = null;
			
			//不停的将a1->a2反转为a2->a1,直到a3为空
			while(a3!=null){
				//a2的后继设为a1
				a2.next = a1;
				//a1、a2、a3依次向后移一位
				a1 = a2;
				a2 = a3;
				a3 = a3.next;
			}
			
			//将最后一个结点反向
			a2.next = a1;
			return a2;
		}
		//PS:这里使用局部代码块一方面增强了代码的可读性,另一方面使得局部代码块中的变量能够在代码块结束之后立即释放,从而节约了内存空间。
	}
}


/**
 * 定义结点 
 */
class Node<T>{
	public T data;
	public Node<T> next;
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Pulsar-V

Save Camera Document

#pragma once #include "HCCamera.h" #include <time.h> #include <cstdio> #incl...

2828
来自专栏CodingToDie

Awesome 项目

3505
来自专栏吴伟祥

Apache POI总结 原

Apache POI  是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office格...

761
来自专栏跟着阿笨一起玩NET

c# 使用timer定时器操作,上次定时到了以后,下次还未执行完怎么处理

------解决方案-------------------------------------------------------- 开始的时候,禁用定时器,你...

2691
来自专栏成长道路

org.apache.spark.sql.AnalysisException: Table or view not found: `traintext`.`train`; line 1 pos 14;

恭喜老铁,跟我遇到了一样的问题,接下来是解决方法: 遇到的问题: org.apache.spark.sql.AnalysisException: Table o...

9380
来自专栏Ryan Miao

ehcache报错

jfinal2.0+tomcat7+ehcache2.6.11+Linux Linux version 2.6.18-164.el5 (mockbuild@x8...

3729
来自专栏IT杂记

Storm客户端提交任务失败原因分析

2570
来自专栏生信技能树

基因名变化太快,比如PAM50

当然准备把这些基因跟ensembl数据库的ID对应的时候我发现少了3个,然后我搜索发现它们的symbol其实被修改了,可以说变化比较快啦,才几年时间,3 of ...

1032
来自专栏码匠的流水账

java9系列(五)Stack-Walking API

java9新增这个类的目的是提供一个标准API用于访问当前线程栈,之前只有Throwable::getStackTrace、Thread::getStackTr...

421
来自专栏linux驱动个人学习

高通Audio中ASOC的machine驱动

ASoC被分为Machine、Platform和Codec三大部分,其中的Machine驱动负责Platform和Codec之间的耦合以及部分和设备或板子特定的...

9784

扫码关注云+社区