写点什么

java 中如何实现单链表反转

作者:秃头小帅oi
  • 2025-02-27
    福建
  • 本文字数:3045 字

    阅读完需:约 10 分钟

java中如何实现单链表反转

1.准备链表准备一个由 DataNode 组成的单向链表,DataNode 如下:csharp 代码解读复制代码 public class DataNode {

private int data;private DataNode next;public int getData() {    return data;}public void setData(int data) {    this.data = data;}public DataNode getNext() {    return next;}public void setNext(DataNode next) {    this.next = next;}public DataNode(int data) {    this.data = data;}
复制代码

}

构造链表 ini 代码解读复制代码 public class DataChain {


private DataNode head;
public DataChain(int size) { DataNode head = new DataNode(0); DataNode cur = head; for (int i = 1; i < size; i++) { DataNode tmp = new DataNode(i); cur.setNext(tmp); cur = tmp; } this.head = head;}
public DataNode getHead() { return head;}
public void setHead(DataNode head) { this.head = head;}
public static void printChain(DataNode head) { StringBuilder sb = new StringBuilder(); DataNode cur = head; sb.append(cur.getData()); while (null != cur.getNext()) { sb.append(" -> "); sb.append(cur.getNext().getData()); cur = cur.getNext(); } System.out.println(sb.toString());}
public static void main(String... strings) { DataChain chain = new DataChain(10); printChain(chain.getHead());}
复制代码

}

运行 main 方法,即构造了一个包含 10 个 node 节点的单链表。rust 代码解读复制代码 #运行结果 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9

2.通过递归实现单链表反转考虑到代码的简洁性,首先考虑的是通过递归实现。java 代码解读复制代码 /**

 * 递归实现 当栈深度大于12000 则会出现StakOverflowError *  * @param head * @return */public static DataNode reverse1(DataNode head) {    if (null == head || null == head.getNext())        return head;    DataNode revHead = reverse1(head.getNext());    head.getNext().setNext(head);    head.setNext(null);    return revHead;}

复制代码

以上即是递归实现的源码,但是需要考虑的问题是递归都在 java 栈中进行,需要考虑 jdk 支持的栈的深度。在 jdk1.8.0_91 版本中,当上述链表长度大于 12000 则会出现 StackOverFlowError 错误。说明对于该版本 jdk 栈的深度不能大于 12000。3.通过遍历实现最通用的实现方式就是遍历。ini 代码解读复制代码/**

 * 遍历实现 通用实现方法 *  * @param head * @return */public static DataNode reverse2(DataNode head) {    if (null == head || null == head.getNext())        return head;    DataNode pre = head;    DataNode cur = head.getNext();    while (null != cur.getNext()) {        DataNode tmp = cur.getNext();        cur.setNext(pre);        pre = cur;        cur = tmp;    }    cur.setNext(pre);    head.setNext(null);    return cur;}
复制代码

4.借助 stack 实现考虑到 stack 具有先进后出这一特性,因此可以借助于 stack 数据结构来实现单向链表的反转。ini 代码解读复制代码/**

 * 方法3 利用其他数据结构 stack  * @param head * @return */public static DataNode reverse3(DataNode head) {    Stack<DataNode> stack = new Stack<DataNode>();    for (DataNode node = head; null != node; node = node.getNext()) {        stack.add(node);    }    DataNode reHead = stack.pop();    DataNode cur = reHead;    while(!stack.isEmpty()){        cur.setNext(stack.pop());        cur = cur.getNext();        cur.setNext(null);    }    return reHead;}
复制代码

上述实现方法在于操作简单,对于算法并不精通的同学可以尝试。缺点在于需要通过其他数据结构实现,效率会降低,至于效率会降低到什么程度,后面举例说明。5.三种实现方式效率分析 ini 代码解读复制代码 public static void main(String... strings) {

    int size = 10;        DataChain chain1 = new DataChain(size);    printChain(chain1.getHead());    long reverse1_start = System.currentTimeMillis();    DataNode reNode1 = reverse1(chain1.getHead());    long reverse1_cost = System.currentTimeMillis() - reverse1_start;    printChain(reNode1);    System.out.println("reverse1 cost time is ["+reverse1_cost+"]ms");        DataChain chain2 = new DataChain(size);    printChain(chain2.getHead());    long reverse2_start = System.currentTimeMillis();    DataNode reNode2 = reverse2(chain2.getHead());    long reverse2_cost = System.currentTimeMillis() - reverse2_start;    printChain(reNode2);    System.out.println("reverse2 cost time is ["+reverse2_cost+"]ms");        DataChain chain3 = new DataChain(size);    printChain(chain3.getHead());    long reverse3_start = System.currentTimeMillis();    DataNode reNode3 = reverse3(chain3.getHead());    long reverse3_cost = System.currentTimeMillis() - reverse3_start;    printChain(reNode3);    System.out.println("reverse3 cost time is ["+reverse3_cost+"]ms");}
复制代码

执行结果:rust 代码解读复制代码 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 99 -> 8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0reverse1 cost time is [0]ms0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 99 -> 8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0reverse2 cost time is [0]ms0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 99 -> 8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0reverse3 cost time is [1]ms

在上述代码基础上,去掉打印输出,将 size 改为 10000,结果如下:css 代码解读复制代码 reverse1 cost time is [1]msreverse2 cost time is [0]msreverse3 cost time is [6]ms

可以看出 reverse2 明显优于其他两种实现方法。考虑到 reverse1 最多只支持 12000,因此将 size 改为 100000 时,再观察 reverse2 和 reverse3 之间的执行结果:css 代码解读复制代码 reverse2 cost time is [6]msreverse3 cost time is [25]ms

因此可以看出,最好的方法是采用遍历的方式进行反转。

行业拓展

近 10 年间,甚至连传统企业都开始大面积数字化时,我们发现开发内部工具的过程中,大量的页面、场景、组件等在不断重复,这种重复造轮子的工作,浪费工程师的大量时间。 针对这类问题,JNPF 低代码平台把某些重复出现的场景、流程,具象化成一个个组件、api、数据库接口,避免了重复造轮子,极大的提高了程序员的生产效率。

体验地址:https://www.jnpfsoft.com

这是一个基于 Flowable 引擎(支持 java、.NET),已支持 MySQL、SqlServer、Oracle、PostgreSQL、DM(达梦)、 KingbaseES(人大金仓)6 个数据库,支持私有化部署,前后端封装了上千个常用类,方便扩展,框架集成了表单、报表、图表、大屏等各种常用的 Demo 方便直接使用。

至少包含表单建模、流程设计、报表可视化、代码生成器、系统管理、前端 UI 等组件,这种情况下我们避免了重复造轮子,已内置大量的成熟组件,选择合适的组件进行集成或二次开发复杂功能,即可自主开发一个属于自己的应用系统。

用户头像

摸个鱼,顺便发点有用的东西 2023-06-19 加入

互联网某厂人(重生版)

评论

发布
暂无评论
java中如何实现单链表反转_秃头小帅oi_InfoQ写作社区