带字符串Java的双链表

带字符串Java的双链表,java,Java,我编写了以下程序: public class DLinkedList<T extends Comparable<T>> { private class DNode<T> { private DNode<T> prev, next; private T nodeValue; public DNode() { nodeValue = null; n

我编写了以下程序:

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);
    }
}
公共类DLinkedList{
私有类DNode{
私有数据节点上一个,下一个;
私人T节点价值;
公共DNode(){
nodeValue=null;
下一个=上一个=这个;
}
公共数据节点(T val){
nodeValue=val;
下一个=上一个=这个;
}
}
专用DNode头;
私有整数大小;
公共数据链接列表(){
header=新的DNode();
尺寸=0;
}
公共布尔空(){
返回大小==0;
}
公共整数大小(){
返回大小;
}
公共无效添加命令(T val){
DNode newNode=新的DNode(val);
DNode curr=标题。下一步;
整数计数=0;
while(curr!=页眉&&
当前nodeValue.compareTo(newNode.nodeValue)<0){
curr=curr.next;
newNode.prev=curr;
newNode.next=curr.next;
newNode.next.prev=curr;
计数++;
}
如果(计数=1){
newNode.prev=curr;
newNode.next=curr.prev;
curr.prev.next.next=newNode;
}否则{
newNode.prev=curr.prev;
newNode.next=curr;
curr.prev.next=newNode;
计数++;
}
}
公共字符串toString(){
字符串str=“”;
DNode curr=标题。下一步;
while(curr!=页眉){
str+=curr.nodeValue+“,”;
curr=curr.next;
}
如果(str.length()>0){
返回str.substring(0,str.lastIndexOf(“,”);
}否则{
返回str;
}
}
公共静态void main(字符串[]args){
DLinkedList d=新的DLinkedList();
d、 追加订单(“t”);
d、 追加订单(“y”);
d、 追加订单(“e”);
d、 追加订单(“b”);
d、 追加订单(“p”);
System.out.println(“列表1:t、y、e、b、p”+”\n添加列表1并排序:“+d”);
}
}
我对如何解决我的问题感到困惑。我想创建一个包含字符串值的节点的双链接列表,当我将这些字符串值添加到列表中时,列表会通过插入排序的方式自动排序

我从一个具有空值的节点调用头开始。然后,当我使用
addOrder(t val)
方法将字符串“t,y,e,b,p”添加到列表中时,一切似乎都正常。它将按排序顺序“b、e、p、t、y”打印出来

如果我决定不在末尾打印“p”,而是执行“t,y,e,b,c”,那么问题就会出现。我打印出来的是“b,c”,而不是“b,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”之间添加任何内容,但在“f-t”之前或之后添加任何内容都可以。我感觉它与我的索引“curr”有关,可能是我的节点头卡住了。

您的一些代码似乎有点混乱。在找到插入点之前,您可以跳过列表中的循环,但它会同时更改新节点的指针和现有节点的指针。我将只在该循环中使用
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++;
            }
while(curr!=标题&&
当前nodeValue.compareTo(newNode.nodeValue)<0){
curr=curr.next;
newNode.prev=curr;
newNode.next=curr.next;
newNode.next.prev=curr;
计数++;
}

我有一个网页,介绍了如何执行这些任务,您可能会发现这很有帮助。

我同意代码有点混乱,您应该从while循环中删除这些任务,但解决方法似乎很简单

在循环后的部分中,您需要在不进行计数检查的情况下切换分配:

newNode.prev = curr.prev;
newNode.next = curr;
curr.prev.next = newNode;
curr.prev = newNode;
在插入“p”时使用“t,y,e,v,p”的示例中,当前光标位于字母“t”上。此时,您希望“p”指向“t”,而previous则是“t”previous,在本例中是“e”


我还没有测试您的其他场景,但这看起来像是您缺少的内容。

感谢您列出所有代码!你能给我们看一些代码吗?编辑:我没有看到顶部的链接,这更容易通过附加调试器来修复?@Paolo然后尝试调试并找到解决方案在方法
addOrder
中,在while循环中,删除从
newNode
开始的所有分配-它们无论如何都会被覆盖。当您还没有找到插入位置时,为什么要修改列表?可能这是一个错误。在方法
toString()
中,使用
StringBuilder
而不是
str+=…
。是的,用户必须了解调试+1对于调试tipI,我非常迷茫,因为我已经破坏了这一天。我想像你说的那样,继续推进curr,直到找到将newNode添加到列表中的位置。看起来,如果我将这些代码输入while循环,它就能够将字符串“e,b”添加到列表中。如果我删除它,它只会打印“p,t,y”。@JavaStudent一次修复一个问题。首先确保可以找到正确的插入点,而无需更改任何内容。将System.out.println调用添加到