我想在同步双向链接列表上实现QuickSort算法。 我给左边和右边的函数“分区”,然后它开始搜索左侧的较低值并将较大的值放在右侧。这是有效的,因为我的枢轴元素总是最右边的元素,在这个步骤之后它位于中间。
我总是得到一个无限循环,我不知道为什么?也许错误的中止条件?
她的代码:
private void quickSortRec(DoublyLinkedList in, ListElement l, ListElement r) {
ListElement pivot = partition(in, l, r);
if(pivot!=null && l!=r){
quickSortRec(in, in.first, pivot.prev);
quickSortRec(in, pivot.next, in.first.prev);
}
}
public ListElement partition(DoublyLinkedList in, ListElement l, ListElement r){
ListElement pivot = r;
ListElement walker = l;
if(l!=r){
while(walker != pivot){
if(walker.getKey() >= pivot.getKey()){
System.out.println(walker.getKey());
if(walker.prev == r){
l = walker.next;
r = walker;
}
else{
ListElement h1 = walker.prev;
ListElement h2 = walker.next;
h1.next = h2;
h2.prev = h1;
walker.prev = pivot;
walker.next = l;
pivot.next = walker;
l.prev = walker;
r = walker;
}
}
walker = walker.next;
}
if(l.prev == r)
in.first = l;
ListElement p = in.first;
do{
System.out.print(p.toString()+" ");
p = p.next;
}while(p != in.first);
System.out.println();
return pivot;
}
return null;
}
}
答案 0 :(得分:1)
只是从快速浏览,似乎您的列表不仅是双重链接,而且在末端连接(因此它更像是一个环而不是列表)。换句话说,如果我要遍历您的列表(包含元素A, B, C, D
),那么它将不是:
A -> B -> C -> D -> stop
相反,它将是
A -> B -> C -> D -> A -> B -> C -> D -> A -> B ..... etc.
我怀疑这可能是你无限循环的原因。
我会在DoublyLinkedList
类(例如:in.last
)中创建对列表的最后一个元素的引用,使用它来获取最后一个元素,并将第一个和最后一个元素链接到null
或某种NullListElement extends ListElement
如果您必须将其保留为响铃,我仍会添加对您列表中最后一个元素的引用,以便您可以这样说:
if(walker == in.last) break; // stop
答案 1 :(得分:1)
Node partition(Node start, Node end){
Node l = start;
Node h = end.previous;
Node pivot = end;
if(end!=null && end.next!=start){ //Whenever deal with end.next, check null check
while(h!=null && h.next!=l){//Whenever deal with end.next, check null check
System.out.println("gumi");
if(l.data<pivot.data)
l=l.next;
else if(h.data>pivot.data)
h=h.previous;
else{
int temp = l.data;
l.data = h.data;
h.data = temp;
}
}
int temp = pivot.data;
pivot.data = l.data;
l.data = temp;
}
return l;
}
void quicksort(Node start, Node end){
System.out.println("jose");
if(end!=null && end.next!=start ){ //Whenever deal with end.next, check null check , end should not be less than start: so the condition end.next!=start
System.out.println("Quixk");
Node pivot = partition(start,end);
quicksort(start, pivot.previous);
quicksort(pivot.next, end);
}
}
答案 2 :(得分:0)
以下是使用DoublyLinkedList
类的 QuickSort 的实现,其中包含对第一个(in.first
)ListElement
的引用,列表元素包含{ {1}}以及key
和prev
引用:
next
在撰写本文时,当我使用最近的Haswel CPU在台式计算机上运行时,我得到以下结果:
<强>快速排序:强>
1.000.000项目:696ms
8.300.000项目:8131ms
请注意,对于相同的数据结构,这比我的MergeSort implementation慢得多,为此我在同一台计算机上使用相同的输入获得以下时间:
<强>归并:强>
1.000.000项目:466ms
8.300.000项目:5144ms
请注意,时间特定于我的硬件,您可能会得到不同的结果。