我写了以下程序:
public class DLinkedList<T extends Comparable<T>> {
private class DNode<T> {
private DNode<T> prev, next;
private T nodeValue;
public DNode() {
nodeValue = null;
next = prev = this;
}
public DNode(T val) {
nodeValue = val;
next = prev = this;
}
}
private DNode<T> header;
private int size;
public DLinkedList() {
header = new DNode<T>();
size = 0;
}
public Boolean empty() {
return size == 0;
}
public int size() {
return size;
}
public void addOrder(T val) {
DNode<T> newNode = new DNode<T>(val);
DNode<T> curr = header.next;
int count = 0;
while (curr != header &&
curr.nodeValue.compareTo(newNode.nodeValue) < 0 ) {
curr = curr.next;
newNode.prev = curr;
newNode.next = curr.next;
newNode.next.prev = curr;
count++;
}
if (count == 1) {
newNode.prev = curr;
newNode.next = curr.prev;
curr.prev.next.next = newNode;
} else {
newNode.prev = curr.prev;
newNode.next = curr;
curr.prev.next = newNode;
count++;
}
}
public String toString() {
String str = "";
DNode<T> curr = header.next;
while (curr != header) {
str += curr.nodeValue + ", ";
curr = curr.next;
}
if (str.length() > 0) {
return str.substring(0, str.lastIndexOf(", "));
} else {
return str;
}
}
public static void main(String[] args) {
DLinkedList<String> d = new DLinkedList<String>();
d.addOrder("t");
d.addOrder("y");
d.addOrder("e");
d.addOrder("b");
d.addOrder("p");
System.out.println("List 1: t, y, e, b, p" + "\nList 1 added and sort : " +d);
}
}
我很困惑/失去了如何解决我的问题。我想创建一个包含String值的节点的双链表,当我将这些字符串值添加到列表中时,列表会通过插入排序对其进行自动排序。
我从一个具有空值的节点调用头开始。然后当我使用addOrder(T val)
方法将字符串“t,y,e,b,p”添加到列表中时,一切似乎都有效。它将按排序顺序“b,e,p,t,y”打印出来。
如果我决定不在末尾打印“p”,而不是“t,y,e,b,c”,那么问题就出现了我打印出的所有内容都是“b,c”,而不是“b,c” c,e,t,y“。如果我在列表的末尾添加“a”而不是“p”或“c”,那么一切似乎都很好地打印“a,b,e,t,y”。所以看起来它适用于所有不是“c,d,e”的东西。好像我需要编写一个方法来编写一个方法来添加一个将在它们之间传递的新节点,我现在已经迷失了这个节点。
如果我决定添加字符串“t,y,e,v,p”,则会出现另一个问题。看起来这只是打印“e,p”。这似乎添加了“t,y,e,v”但是当“p”进入时,它会掉落“t,y,v”并离开“e,p”。
似乎我无法在“f-t”之间添加任何内容,但在此之前或之后的任何内容都可以。我有一种感觉,它与我的索引“curr”有关,可能它与我的节点标题一致。
答案 0 :(得分:1)
你的一些代码似乎有点困惑。在找到插入点之前,您有一个跳过列表的循环,但它会更改新节点的指针和现有指针。我会在该循环中只有curr = curr.next
,并且在找到要插入的位置之后,在新节点的指针或现有列表中根本不做任何更改,然后记住你需要更改总共四个指针:新节点中的下一个和上一个,前一个指针中的下一个指针,以及其后续指针中的前一个指针。
while (curr != header &&
curr.nodeValue.compareTo(newNode.nodeValue) < 0 ) {
curr = curr.next;
newNode.prev = curr;
newNode.next = curr.next;
newNode.next.prev = curr;
count++;
}
我有一个关于如何debug的网页,您可能会觉得有帮助。
答案 1 :(得分:1)
我同意代码有点令人困惑,你应该从while循环中删除赋值,但修复似乎很简单。
在循环后的部分中,您需要通过计数检查来切换作业:
newNode.prev = curr.prev;
newNode.next = curr;
curr.prev.next = newNode;
curr.prev = newNode;
在插入“p”时使用“t,y,e,v,p”的示例中,当前光标位于字母“t”上。此时,您希望“p”指向“t”,前一个指向前面的“t”,在本例中为“e”。
我还没有测试过你的其他场景,但这看起来就像你缺少的那样。