Java 双链表上的冒泡排序

Java 双链表上的冒泡排序,java,linked-list,bubble-sort,Java,Linked List,Bubble Sort,为此,我花了几个小时试图让气泡排序的实现在一个双链接列表上工作。我的代码似乎只运行了一次,但没有完成排序就过早地结束了。任何指导都将不胜感激 public void bubbleSort() { Node cur = head.getNext(); boolean done = false; while (!done) { done = true; while(cur != tail) {

为此,我花了几个小时试图让气泡排序的实现在一个双链接列表上工作。我的代码似乎只运行了一次,但没有完成排序就过早地结束了。任何指导都将不胜感激

public void bubbleSort()
{
    Node cur = head.getNext();
    boolean done = false;

    while (!done)
    {
        done = true;
        while(cur != tail)
        {
            if (cur.getNext().getCount()>cur.getCount())
            {
                swap(cur.getNext(),cur);
                done=false;
            }
            cur = cur.getNext();
        }
    }
} 
我使用的交换方法似乎破坏了节点的位置,直到它成为两个节点之间的循环

private void swap(Node n1, Node n2)
{
    Node b1, b2, a1, a2;
    System.out.println("Swapping n1: " + n1 + " with n2: " + n2);
    b1 = n2.getPrev();
    if (b1 == n1) // handle adjacent nodes
        b1 = n2;
    a1 = n2.getNext();

    b2 = n1.getPrev();
    if (b2 == n2) // handle adjacent nodes
        b2 = n1;
    a2 = n1.getNext();

    // swap

    n1.setPrev(b1);
    n1.setNext(a1);

    n2.setPrev(b2);
    n2.setNext(a2);

    b1.setNext(n1);
    a1.setPrev(n1);

    b2.setNext(n2);
    a2.setPrev(n2);
}

感谢添加
cur=head.getNext()对于我的链表实现很好。因此,问题在于
swap
方法或列表的实现


根据您的
bubbleSort
方法,
swap
方法只交换节点的数据,而不是节点本身。我的意思是,它只是交换
count
的值。如果不是这样的话,
swap
方法就是问题所在。否则,您的双链表实现就会出现问题。

您肯定需要保留
cur=head.getNext()在外部while循环的末尾,否则在第二次传递时,将完全跳过内部while循环,并且done将为true


您是否考虑过冒泡排序的运行时间?我注意到,在您对MD.Unicorn的回答中,它可以很好地列出我在代码中看到的问题:

  • 您应该从
    头开始,而不是从
    头开始。getNext()
  • 当(!done)
迭代时,应在每次
上重新启动
节点cur
通过这些更改,您的代码应该

public void bubbleSort() {
    boolean done = false;
    while (!done) {
        Node cur = head;
        done = true;
        while(cur != tail) {
            if (cur.getNext().getCount()>cur.getCount()) {
                swap(cur.getNext(),cur);
                done=false;
            }
            cur = cur.getNext();
        }
    }
}
此代码假定您的
swap
方法工作正常。使用
int count
作为
节点中的数据进行测试,在列表中指定10000个int值


编辑:根据您的问题编辑,我将我的
节点
类和
交换
功能如下:

private static class Node {
    int count;
    Node next;
    //getters and setters...
}

//this function just swaps data, no need to swap the nodes prev and next
//(note that yours is an algorithm design issue)
private void swap(Node node1, Node node2) {
    int aux = node1.getCount();
    node1.setCount(node2.getCount());
    node2.setCount(aux);
}

无需执行您在
交换
实现中执行的所有样板代码。

为什么不在链表中编写一个比较器,将一个元素与其直接后续元素交换是一种特殊情况。那个案例经过测试了吗?对于外部循环的每次迭代,您确实需要返回列表的开头。对于简单的列表,请逐步运行代码,并观察其行为。感谢您的帮助。这绝对是交换方法。现在我只需要找出问题所在。对于一个简单的n<100列表,它可以正常工作,但是对于我正在测试的n=1000列表,我失败了。在我的计算机中,100个元素需要4390ms到5038ms,1000个元素需要12740ms到13608ms。然后我得到一个空指针错误,因为头部和尾部是哨兵标记。这是我非常确定的交换方法。@efnx我想您的LinkedList实现中有问题=\。我做了一个快速测试,工作得非常出色。@efnx根据你的问题编辑,你为什么有那么多样板代码?您只需要交换节点中的数据!