双链表上的冒泡排序
Posted
技术标签:
【中文标题】双链表上的冒泡排序【英文标题】:Bubble sort on double linked list 【发布时间】:2013-02-24 03:25:41 【问题描述】:花了几个小时试图让冒泡排序的实现在双链表上工作。我的代码似乎可以通过一次,但在没有完成排序的情况下过早完成。任何指导将不胜感激。
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);
谢谢
【问题讨论】:
为什么不写一个比较器javarevisited.blogspot.com/2011/06/… 在链表中,将一个元素与其直接后继元素交换是一种特殊情况。那个案例有过测试吗?对于外循环的每次迭代,您确实需要返回到列表的开头。 逐步运行代码以获得一个简单的列表,并观察它的行为。 【参考方案1】:我在您的代码中看到的问题:
你应该从head
开始,而不是从head.getNext()
开始。
您应该在每次 while(!done)
迭代时重新启动 Node 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
作为 Node
类中的数据进行测试,在列表中分配 10000 个 int 值。
编辑:根据您的问题编辑,我将Node
类和swap
函数设为:
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);
无需执行您在 swap
实现中完成的所有样板代码。
【讨论】:
然后我得到一个空指针错误,因为头部和尾部是哨兵标记。我很确定这是交换方法。 @efnx 我猜你的 LinkedList 实现有问题 =\。我做了一个快速测试,并像一个魅力一样工作。 @efnx 根据您的问题编辑,您为什么拥有所有样板代码?您只需要交换节点中的数据!【参考方案2】:在外循环的开头添加cur = head.getNext();
对我的链表实现很有效。所以问题出在swap
方法或者你的列表的实现上。
根据您的bubbleSort
方法,swap
方法只交换节点的数据,而不是节点本身。我的意思是,它只是交换count
的值。如果不是这样,swap
方法就是问题所在。否则,你的双链表实现会有问题。
【讨论】:
感谢您的帮助。这绝对是交换方法。现在我只需要弄清楚出了什么问题。对于一个简单的 n 【参考方案3】:您绝对需要将cur = head.getNext();
保留在外部while 循环的末尾,否则在第二次通过时内部while 循环将被完全跳过并且完成将是真的。
您是否考虑过冒泡排序的运行时间?我在您对 MD.Unicorn 的回答中注意到,它适用于
对 100 个列表进行排序需要多长时间?
【讨论】:
在我的计算机中,100 个元素需要 4390 毫秒到 5038 毫秒,1000 个元素需要 12740 毫秒到 13608 毫秒。以上是关于双链表上的冒泡排序的主要内容,如果未能解决你的问题,请参考以下文章