Java 指定范围的链表反转

  • Post author:
  • Post category:java




给定一个单向链表, 反转指定范围内的节点



链表反转的大致思路

反转链表只需要不断地将当前节点的下一个节点的 next 指向当前节点, 然后将下个节点设置为当前节点,

设置两个引用, cur, next 分别指向当前和下一个节点

如图所示: cur–>1, next–>2

反转操作为:

next.next-->cur


然后移动

cur

,

next

一次反转后: 当前为2, 下一个为3

 markdown 竟然不能画图....

循环操作, 就完成了所有的反转



指定范围的链表反转

和全部反转一样, 相当于把链表分为了三段, 反转中间那段, 再将三段连接起来

所以只需要将反转范围的前一个节点

1

和 反转范围内第一个节点

2

(反转后的最后一个) 引用保存下来, 用于反转后的连接. 然后对中间的进行反转



反转操作完成后

markdown 不能画图!!!

所以最后需要让节点

1

指向

cur

,

2

指向

next

, 就完成了



以下是代码:
public class ReverseLink {


    private static class Node {
        int value;
        Node next;

        Node(int value) {
            this.value = value;
        }
    }

    public static void main(String[] args) {

        // 初始化链表
        Node head = new Node(0);
        Node cur;
        Node last = head;
        for (int i = 1; i < 15; i++) {
            cur = new Node(i);
            last.next = cur;
            last = cur;
        }

        printLink(head);
        // 反转
        Node reversed = reverse(head, 3, 5);
        printLink(reversed);

    }

    /**
     * 反转从 begin 到 end 范围的节点
     * @param node 链表头结点
     * @param begin 开始的位置
     * @param end 结束位置
     * @return 返回链表头结点
     */
    private static Node reverse(Node node, int begin, int end) {

        Node bNode = null;      // 记录反转开始的前一个
        Node eNode = null;      // 记录反转开始的第一个, 即反转的最后一个
        Node cur = node;
        
        // 找到开始反转的位置
        for (int i = 0; i < begin - 1; i++) {
            if (cur == null) {
                return node;
            }
            bNode = cur;
            cur = cur.next;
        }
        eNode = cur;

        Node nNode = cur.next;      // 下一个
        Node nnNode = null;        // 下下个
        // 进行反转
        for (int i = 0; i < end - begin; i++) {
            if (nNode != null) {
                nnNode = nNode.next;      // 先保存下下个的引用
                nNode.next = cur;       // 下一个指向当前的 (反转)
                cur = nNode;            // 移动cur, 指向下一个
                if (nnNode == null) {
                    break;
                }
                nNode = nnNode;
            }
        }

        // 将反转后的链表和两端连接
        bNode.next = cur;
        eNode.next = nnNode;

        return node;
    }


    /**
     * 打印链表节点值
     * @param head
     */
    private static void printLink(Node head) {
        while (head != null) {
            System.out.print(head.value + " -> ");
            head = head.next;
        }
        System.out.println();
    }
}

运行结果贴一下:

// 反转前
0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> 11 -> 12 -> 13 -> 14 -> 

// 反转后
0 -> 1 -> 4 -> 3 -> 2 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> 11 -> 12 -> 13 -> 14 -> 



版权声明:本文为Wu_Shang001原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。