Java实现单链表反转的多种方法总结
作者:起个花名好难 发布时间:2023-11-11 02:28:08
标签:java,单链表,反转
对于单链表不熟悉的可以看一下基于Java实现单链表的增删改查
一、原地反转
1、新建一个哨兵节点下一结点指向头结点
2、把待反转链表的下一节点插入到哨兵节点的下一节点
反转之前的链表:1–>2–>3–>4>–>5
加入哨兵节点:dummp–>1–>2–>3–>4>–>5
原地反转:
定义:prev=dummp.next; pcur=prev.next;
prev.next=pcur.next;
pcur.next=dummp.next;
dummp.next=pcur;
pcur=prev.next;
public Stu_node reverse_list(Stu_node head){
if (head.next==null ||head.next.next==null)
return null;
Stu_node dump = new Stu_node(-1," ");
dump.next=head;
Stu_node prev = dump.next;
Stu_node pcur = prev.next;
while(pcur!=null){
prev.next=pcur.next;
pcur.next=dump.next;
dump.next=pcur;
pcur=prev.next;
}
return dump.next;
}
二、新建链表头结点插法
二、新建链表头结点插法:
新建一个头结点,遍历原链表,把每个节点用头结点插入到新建链表中。最后,新建的链表就是反转后的链表。
public Stu_node reverse_list1 (Stu_node head){
//新建一个新的链表的头结点
Stu_node dump = new Stu_node(-1," ");
Stu_node pcur = head;
//遍历待反转链表,头结点插入到新的链表中
while(pcur!=null){
Stu_node pnext = pcur.next;
pcur.next = dump.next;
dump.next=pcur;
pcur=pnext;
}
//新链表头结点不是需要返回的数据,因此返回头结点的下一节点
return dump.next;
}
三、利用栈结构实现链表的反转
由于栈结构存储数据是先进后出(后进先出)也可以通过栈达到反转链表的目的。
public Stu_node reverse_stack(Stu_node head){
Stack<Stu_node> stack = new Stack<>();
Stu_node temp = head;
//链表入栈
while(temp!=null){
stack.push(temp);
temp=temp.next;
}
//取出栈中的一个节点当做新的链表的头结点
Stu_node new_head = stack.pop();
Stu_node cur = new_head;
//出站
while(!stack.isEmpty()){
Stu_node node = stack.pop();
//将出站的节点指向取消
node.next=null;
//将新的链表串起来
cur.next = node;
cur = node;
}
return new_head;
}
四、完整代码奉上
import java.util.Stack;
public class revere_node {
public static void main(String[] args) {
LinkedNode list= new LinkedNode();
Stu_node node1 = new Stu_node(1,"张三");
Stu_node node2 = new Stu_node(2,"李四");
Stu_node node3 = new Stu_node(3,"王二");
Stu_node node4 = new Stu_node(4,"麻子");
Stu_node node5 = new Stu_node(5,"赵六");
//打印添加节点之前的链表
list.print();
//尾结点添加节点
list.add(node1);
list.add(node2);
list.add(node3);
list.add(node4);
list.add(node5);
//打印添加加点之后的链表
list.print();
System.out.println("-------------------");
//定义一个头结点接收调用函数返回的头节点
Stu_node head = list.reverse_stack(list.head);
//遍历输出每个节点
while (head.next!=null){
System.out.println(head);
head=head.next;
}
}
}
//定义一个链表的操作类
class LinkedNode{
//定义一个头结点
Stu_node head = new Stu_node(-1," ");
//添加链表的方法
public void add(Stu_node node){
Stu_node temp = head;
while(true){
if (temp.next==null)
break;
temp=temp.next;
}
temp.next=node;
}
//打印链表
public void print(){
Stu_node temp = head.next;
if (head.next==null){
System.out.println("此链表为空");
}
while (temp!=null){
System.out.println(temp);
temp=temp.next;
}
}
//原地反转
public Stu_node reverse_list(Stu_node head){
if (head.next==null ||head.next.next==null)
return null;
Stu_node dump = new Stu_node(-1," ");
dump.next=head;
Stu_node prev = dump.next;
Stu_node pcur = prev.next;
while(pcur!=null){
prev.next=pcur.next;
pcur.next=dump.next;
dump.next=pcur;
pcur=prev.next;
}
return dump.next;
}
//新建一个新的链表,头结点插入法实现链表的反转
public Stu_node reverse_list1 (Stu_node head){
Stu_node dump = new Stu_node(-1," ");
Stu_node pcur = head;
while(pcur!=null){
Stu_node pnext = pcur.next;
pcur.next = dump.next;
dump.next=pcur;
pcur=pnext;
}
return dump.next;
}
//利用栈实现反转链表
public Stu_node reverse_stack(Stu_node head){
Stack<Stu_node> stack = new Stack<>();
Stu_node temp = head;
//链表入栈
while(temp!=null){
stack.push(temp);
temp=temp.next;
}
//取出一个节点当做新的链表的头结点
Stu_node new_head = stack.pop();
Stu_node cur = new_head;
//出站
while(!stack.isEmpty()){
Stu_node node = stack.pop();
//将出站的节点指向取消
node.next=null;
//将新的链表串起来
cur.next = node;
cur = node;
}
return new_head;
}
}
//节点类
class Stu_node{
int num;
String name;
Stu_node next;
//重写toString方法,显示节点数据
@Override
public String toString() {
return "Stu_node{" +
"num=" + num +
", name='" + name + '\'' +
'}';
}
public Stu_node(int num, String name) {
this.num = num;
this.name = name;
}
}
总结
来源:https://blog.csdn.net/cly_32/article/details/115572555


猜你喜欢
- 1. 前言Spring的核心技术IOC(Intorol of Converse控制反转)的实现途径是DI(dependency Insert
- 什么是不可变对象?String对象是不可变的,但这仅意味着你无法通过调用它的公有方法来改变它的值。众所周知, 在Java中, String类
- 学习初衷:在工作实际开发过程中,原有的安卓控件已不能满足实际的功能需求,而且有些应用还需要一些独特的展示效果,这时就需要自定义控件来定制控件
- 本文实例为大家分享了Java实现递归计算n的阶乘的具体代码,供大家参考,具体内容如下问题描述利用递归的思想实现阶乘的计算,以 n!为例(一)
- PageAdapter是一个抽象类,直接继承于Object,导入包android.support.v4.view.PagerAdapter即
- 前言已经有两个月没有更新博客了,其实这篇文章我早在两个月前就写好了,一直保存在草稿箱里没有发布出来。原因是有一些原理性的东西还没了解清楚,最
- 1.准备工作1、JDK安装2、Maven安装3、Git安装4、jenkins安装以上软件安装成功后进入jenkins进行相关配置。如果需要通
- 本文实例为大家分享了Qt实现计算器功能的具体代码,供大家参考,具体内容如下该计算器主要通过lineEdit获取和显示数字,通过tablevi
- 缘起公司医疗业务人手比较少【小而美】的团队~ 较少采用的前端技术架构是:toC:小程序 toB2C: Flutter + H5(SPA -
- pom.xml增加依赖包 <dependency> <groupId>io.springf
- 摘要:vs2019新鲜出炉,配置opencv又有哪些不一样呢,这个教程将会一步一步的教你如何配置opencv和跑动opencv一个简单的项目
- 0x00 关于AndroidManifest.xmlAndroidManifest.xml 是每个android程序中必须的文件。它位于整个
- /* String name = "adsbsadgsadgtewterfsdf"
- 前言本文准确来讲是探讨如何用 Jackson 来序列化 Apache avro 对象,因为简单用 Jackson 来序列化 Apache a
- 一、系统介绍1.开发环境开发工具:Eclipse2021JDK版本:jdk1.8Mysql版本:8.0.132.技术选型Java+Swing
- 协程与并发Kotlin协程是基于线程执行的。经过一层封装以后,Kotlin协程面对并发,处理方式与Java不同。在java的世界里,并发往往
- 在我的工作经验中,在C#语言本身的学习上花了大量的时间,积累了一些经验,一些是在学习和工作中遇到的问题和解决办法分享出来,希望大家也能有收获
- 先上效果图: 工具类在解析的过程中,我们会和byte做各种运算,所以我定义了一个byte工具类ByteUtils:using Sy
- 曾经自学C#做计算机图形学的作业,GDI+画图确实好用,目前在找.NET的实习,尝试做了一个最基本的五子棋,复习一下C#的基本语法,目前只能
- 方法重写与之前的方法重载不同回顾一下方法重载,相同的方法名不同参数类型和参数数量以及参数顺序package Demo1;import jav