【问题标题】:Java Double Linked List, Swap NodeJava 双链表,交换节点
【发布时间】:2015-03-11 10:19:03
【问题描述】:

我在 Java 中实现双链表时遇到了问题。特别是交换 2 个以下节点(在我的情况下,一个节点包含一个政治候选人)。
假设以下 DLL:
head-->1 -->2 --> 3 -->4 -->tail

public static void reverseTwoNode(Node<Candidate> N1, Node<Candidate> N2){
     N1.setNextNode(N2.getNextNode()); 
        N2.setPreviousNode(N1.getPreviousNode());

        if (N1.getNextNode() != null)
            N1.getNextNode().setPreviousNode(N1);

        if (N2.getPreviousNode() != null)
            N2.getPreviousNode().setNextNode(N2);


        N2.setNextNode(N1); 
        N1.setPreviousNode(N2);
}

作为输出,我没有从头到尾正确的 DLL,但从头到尾都很好:

List of candidate 
head-->Jacques-->Joseph-->Francis-->Gilbert-->tail
Reverse
tail-->Gilbert-->Francis-->Joseph-->Jacques-->head

Reverse nodes : Francis , Joseph
List of candidate 
head-->Jacques-->Joseph-->Gilbert-->tail
Reverse
tail-->Gilbert-->Joseph-->Francis-->Jacques-->head

我已经编写了这个方法 reverseTwoNode 的几个版本。 我什至尝试在节点内交换数据而不是交换节点,我有同样的问题。 很高兴你能帮助我,我花了这么多小时来使用这个简单的功能,我看不出有什么打扰...... 提前谢谢你,

也许是显示方法的结果??

 /* Display DLL from head to tail
 * @see java.lang.Object#toString()
 * @return str
 */
public String toString(){
    String str = "List of candidate \n";
    str += "head-->";

    Node<Candidate> iterator = this.getHead();

    while (iterator != null) {
        str += iterator.getCandidate().getName();
        str += "-->";
        iterator = iterator.getNextNode();
        }
    return str + "tail";    
}


/**
 * Return string that display DLL from tail to head
 * @return str
 */
public String reverseToString(){
    String str = "Reverse\n";
    str += "tail-->";

    Node<Candidate> iterator = this.getTail();

    while (iterator != null) {
        str += iterator.getCandidate().getName();
        str += "-->" ;
        iterator = iterator.getPreviousNode();
        }

    return (str + "head");
}

解决方案: 我的方法 addNode 是假的,这是在尾部添加节点的正确方法:

public void addNode(Node<Candidate> C){
    if(tail == null){
        this.head = C;
        this.tail = C;
    }
    else{
        this.tail.setNextNode(C);
        this.tail.getNextNode().setPreviousNode(this.tail);
        this.tail = this.tail.getNextNode();
        this.tail.setNextNode(null);
    }   
    this.size ++;
}

【问题讨论】:

  • 我认为您没有将第一个节点保存在辅助节点中。所以当你做 N1.setNextNode 时你会删除它。我不太确定。
  • 对不起,首先,我没有实现编辑。 =) N1 和 N2 相互跟随 N1-->N2 和 N1

标签: java list linked-list doubly-linked-list


【解决方案1】:

如果满足以下假设,则发布的代码有效:

  • N1 和 N2 是相邻节点
  • N1 在 N2 之前(N1 --> N2 和 N1
  • N1 和 N2 都不是头部或尾部元素(因为 reverseTwoNode 不会更新列表)

查看:http://ideone.com/3AKsBx

对于更通用的解决方案,您需要一些辅助变量来存储 N1 / N2 下一个和上一个引用。因为当你这样做时:

N1.setNextNode(N2.getNextNode()); 
N2.setPreviousNode(N1.getPreviousNode());

然后在:

if (N1.getNextNode() != null)
    N1.getNextNode().setPreviousNode(N1);

N1.getNextNode() 不是原始值。由于N1.setNextNode(N2.getNextNode()),它是N2.getNextNode()

这里是一个例子:http://ideone.com/voaaTO

【讨论】:

    【解决方案2】:

    删除 if 语句,因为它们会阻止您移动头部和尾部节点(当一个节点实际指向 null 时可能会导致奇怪的问题)。 我还假设您要交换两个节点,而不管它们的位置如何(不必是两个相邻的节点)。

    这应该只是交换节点并保持列表的其余部分不变。

    public static void reverseTwoNode(Node<Candidate> N1, Node<Candidate> N2){
        Node<Candidate> prevNode1 = N1.getPreviousNode();
        Node<Candidate> nextNode1 = N1.getNextNode();
        Node<Candidate> prevNode2 = N2.getPreviousNode();
        Node<Candidate> nextNode2 = N2.getNextNode();
    
        if(N2.getPreviousNode().equals(N1)) { // test for adjacent nodes
            N2.setPreviousNode(prevNode1);
            N2.setNextNode(N1);
            N1.setNextNode(nextNode2);
            N1.setPrevNode(N2);
        } else {
            N1.setPreviousNode(prevNode2);
            N1.setNextNode(nextNode2);
            N2.setPreviousNode(prevNode1);
            N2.setNextNode(nextNode1);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多