【问题标题】:reverse linked list between given nodes in doubly linked list - algorithm双向链表中给定节点之间的反向链表 - 算法
【发布时间】:2016-04-29 14:28:30
【问题描述】:

我正在编写用于在给定节点之间反转双向链表的代码。

给定这个链表1->2->3->4->5

函数 reverse(2,4) 应该导致 1->4->3->2->5.

该函数有两个节点,但没有索引。

这就是我所拥有的。我尝试了 Eclipse 调试器来弄清楚为什么它会无限期地运行。由于某些原因,我看到节点已损坏(当我单步执行下面标记的行时,Eclipse 未显示任何数据)

public static void reverse(Node head, Node tail){
        Node prev=head.prev;
        Node current=head,next;
        while(current!=tail.next){
            next = current.next;
            current.next=prev;
            current.prev=next; //No data stepping after this point
            prev=current;
            current=next;
        }
    }

public static void main(String... args){
        Node one = new Node(1);
        Node two = new Node(2);
        Node three = new Node(3);
        Node four = new Node(4);
        Node five = new Node(5);

        five.setNodes(four, null);
        four.setNodes(three, five);
        three.setNodes(two,four);
        two.setNodes(one,three);
        one.setNodes(null, two);

        System.out.println("before reversing...");
        System.out.println(one);

        System.out.println("After reversing...");
        reverse(two,four);
        System.out.println(one);

}

这是我的节点类

class Node {
     Node prev;
     Node next;
     int data;

     public Node(Node prev, Node next, int val){
         this.prev=prev;
         this.next=next;
         this.data=val;
     }

     public Node(int val){
         this(null,null,val);
     }

     public void setNodes(Node prev, Node next){
         this.next=next;
         this.prev=prev;
         }

     public String toString(){
         String toReturn = "[ " + this.data;

         Node current=this.next;
         while (current!=null){
             toReturn+=" -> " + current.data;
             current=current.next;
         }
         toReturn+=" ]";
         return toReturn;
     }

}

【问题讨论】:

  • Node current=head,next; 是错字(逗号)吗?应该是Node current=head.next;
  • @brainstorm 注意 toString 方法。

标签: java algorithm data-structures linked-list doubly-linked-list


【解决方案1】:

试试这个:

public static void reverse(Node head, Node tail) {
    Node first = head;
    Node last = tail;
    while (first != last && first.prev != last) {
        Node preFirst = first.prev;
        Node postFirst = first.next;
        Node preLast = last.prev;
        Node postLast = last.next;
        if (preFirst != null) {
            preFirst.next = last;
        }
        if (postLast != null) {
            postLast.prev = first;
        }
        last.prev = preFirst;
        first.next = postLast;
        if (last != postFirst){
            last.next = postFirst;
            postFirst.prev = last;
            first.prev = preLast;
            preLast.next = first;
            first = postFirst;
            last = preLast;
        } else {
            last.next = first;
            first.prev = last;
        }
    }
}

小心 toString 方法,它非常重要,即使是调试也是如此!

public String toString(){
     String toReturn = "[ " + this.data;

     Node current=this.next;
     while (current!=null && current != this){ // <- cycle protection
         toReturn+=" -> " + current.data;
         current=current.next;
     }
     toReturn+=" ]";
     return toReturn;
 }

编辑

它总是返回头节点:

public static Node reverse(Node head, Node tail) {
    Node first = head;
    Node last = tail;
    while (first != last && first.prev != last) {
        Node preFirst = first.prev;
        Node postFirst = first.next;
        Node preLast = last.prev;
        Node postLast = last.next;
        if (preFirst != null) {
            preFirst.next = last;
        }
        if (postLast != null) {
            postLast.prev = first;
        }
        last.prev = preFirst;
        first.next = postLast;
        if (last != postFirst){
            last.next = postFirst;
            postFirst.prev = last;
            first.prev = preLast;
            preLast.next = first;
            first = postFirst;
            last = preLast;
        } else {
            last.next = first;
            first.prev = last;
        }
    }
    Node result = tail;
    while (result.prev != null){
        result = result.prev;
    }
    return result;
}

例子:

public static void main(String... args) {
    Node one = new Node(1);
    Node two = new Node(2);
    Node three = new Node(3);
    Node four = new Node(4);
    Node five = new Node(5);

    five.setNodes(four, null);
    four.setNodes(three, five);
    three.setNodes(two, four);
    two.setNodes(one, three);
    one.setNodes(null, two);

    System.out.println("before reversing...");
    System.out.println(one);

    System.out.println("After reversing...");
    one = reverse(one, three);
    System.out.println(one);
}

打印:

before reversing...
[ 1 -> 2 -> 3 -> 4 -> 5 ]
After reversing...
[ 3 -> 2 -> 1 -> 4 -> 5 ]

【讨论】:

  • 当我在纸上浏览上面的代码时,我发现它应该可以工作。但它没有!感谢您指出 toString 方法中的错误
  • @brainstorm 您必须交换这对节点!认为前头和后尾必须正确链接,您应该能够反转奇数/对节点数(2,4 ) 和 (3,4)
  • 你为什么要交换?您必须在给定节点之间反转。
  • @brainstorm 抱歉,已编辑!超出了 null 保护范围!
  • @brainstorm 我尝试保留原始界面,但在这里我为您的建议进行了编辑
猜你喜欢
  • 2019-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多