单链表逆置-java(递归与非递归)

单链表逆置-java(递归与非递归)

结点是一个自定义的类Node:

private class Node {
    public int value;
    public Node nextNode;
    public Node(int value) {
        this.value = value;
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

递归方法用的是栈的思想,想把头结点入栈,接着头结点的下一个结点入栈,直到尾结点位置, 
截止依次把栈内的元素出栈,并更换其下一个结点对应的对象:

/**
 * 逆置单链表(递归)
 * @param head 头结点
 * @return 逆置后的头结点
 */
private static Node revert(Node head) {
    if (head == null || head.nextNode == null) {
        // 到达尾结点
        return head;
    }
    // 一直入栈
    Node revertHead = revert(head.nextNode);
    // 出栈并赋值nextNode对象
    head.nextNode.nextNode = head;
    head.nextNode = null;
    // 返回尾结点(逆置后的头结点)
    return revertHead;
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

非递归的方法其实就是顺着头结点往尾结点便利,便利期间把每个结点的nextNode替换掉, 
替换过程需要注意临时存储下一个结点:

/**
 * 逆置单链表(非递归)
 * @param head 头结点
 * @return 逆置后的头结点
 */
private static Node revert2(Node head) {
    Node pre = head;
    Node cur = head.nextNode;
    Node tmp;
    // 头结点的nextNode应该要置空
    pre.nextNode = null;
    while (cur != null) {
        // 先存放nex结点
        tmp = cur.nextNode;
        // 修改next结点指向pre
        cur.nextNode = pre;
        pre = cur;
        cur = tmp;
    }
    return pre;
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

验证:

  1. 接着初始化一个单链表,
  2. 调用递归方式将链表逆置,并输出
  3. 调用非递归方式将链表再次逆置(还原到最初状态),并输出

代码如下:

Node head = new Node(0);
Node cur = null;
Node tmp;
for (int i = 1; i <= 10; i++) {
    tmp = new Node(i);
    if (i == 1) {
        head.nextNode = tmp;
    } else {
        cur.nextNode = tmp;
    }
    cur = tmp;
}

// 递归方式
head = revert(head);
System.out.println("递归方式");
printNodes(head);

// 循环方式
head = revert2(head);
System.out.println("循环方式");
printNodes(head);
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

其中printNodes是输出方法:

private static void printNodes(Node head) {
    System.out.print(head.value + "\t");
    while (head.nextNode != null) {
        System.out.print(head.nextNode.value + "\t");
        head = head.nextNode;
    }
    System.out.println();
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

输出结果: 
结果


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值