剑指offer代码解析——面试题16反转单链表
时间:2022-05-03
本文章向大家介绍剑指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;
}
- centos7下卸载python后yum不能使用的恢复方法
- hdu---(5038)Grade(胡搞)
- shell生成随机字符的几种方法
- Python时间获取及转换
- spark streaming知识总结[优化]
- 让你真正明白spark streaming
- Centos7 firewalld防火墙基本操作
- Spark Sql系统入门4:spark应用程序中使用spark sql
- Flume+Kafka收集Docker容器内分布式日志应用实践
- CentOS7搭建ELK日志集中分析平台
- Centos安装sshfs实现挂载目录
- shell脚本监控磁盘使用率
- Python使用MD5加密字符串
- Spark MLlib之 KMeans聚类算法详解
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 学习Python你必须了解的lenna小姐姐
- 10行python代码制作笑死人不偿命的倒放gif
- “Hello Node.js” 这一次是你没见过的写法
- 作为DBA,你不得不掌握的压测工具
- Mac之vim普通命令使用
- selenium库的基本使用
- 高效大数据开发之 bitmap 思想的应用
- 从0到1实现一个虚拟DOM
- Xenomai XDDP example and Posix Compling
- 项目实践|基于Flink的用户行为日志分析系统
- 手把手教你用Matplotlib画一个小清新配色的商业图表
- 高并发场景下锁的使用技巧
- Struts2第四天:Struts2的拦截器和标签库
- kubernete编排技术八:使用operator管理有状态应用
- Spring第一天:Spring的概述、SpringIOC入门(XML)、Spring的Bean管理、Spring属性注入