双链表上的QuickSort

时间:2013-04-30 14:48:16

标签: java sync quicksort doubly-linked-list

我想在同步双向链接列表上实现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;
}


}

3 个答案:

答案 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.firstListElement的引用,列表元素包含{ {1}}以及keyprev引用:

next

在撰写本文时,当我使用最近的Haswel CPU在台式计算机上运行时,我得到以下结果:

<强>快速排序:
1.000.000项目:696ms
8.300.000项目:8131ms

请注意,对于相同的数据结构,这比我的MergeSort implementation慢得多,为此我在同一台计算机上使用相同的输入获得以下时间:

<强>归并:
1.000.000项目:466ms
8.300.000项目:5144ms

请注意,时间特定于我的硬件,您可能会得到不同的结果。