簡體   English   中英

Java中鏈表上的Quicksort實現

[英]Quicksort implemention on linkedlist in java

我用Java編寫了自己的鏈表,它可以正常工作,但是當我想實現quicksort算法時,它給出的輸出很奇怪。

分別列出元素= 50、30、20、10、40、60輸出:10 20 30 40 50 60

分別列出元素= 50、30、10、40、20、60輸出:10 30 20 40 50 60

我嘗試調試,但無法解決

public Node findByIndex(int index) {
    Node current = first;

    for (int i = 0; i < index; i++) {
        current = current.next;
    }

    return current;
}

public int listSize() {
    Node current = first;
    int count = 0;
    while (current != null) {
        current = current.next;
        count++;
    }

    return count;
}

public void sortList() {
    sortList(0, listSize() - 1);
}

public void sortList(int low, int high) {
    Node pivot = findByIndex((low + high) / 2);
    int x = low, y = high;

    while (x <= y) {
        while (findByIndex(x).data < pivot.data) {
            x++;
        }

        while (findByIndex(y).data > pivot.data) {
            y--;
        }

        if (x <= y) {
            swap(x, y);
            x++;
            y--;
        }
    }

    if (x < high)
        sortList(x, high);
    if (low < y)
        sortList(low, y);
}

public void swap(int x, int y) {
    int temp = findByIndex(x).data;
    findByIndex(x).data = findByIndex(y).data;
    findByIndex(y).data = temp;
}

這是發生了什么:

首先,您的列表是:

┌──┬──┬──┬──┬──┬──┐
│50│30│10│40│20│60│
└──┴──┴──┴──┴──┴──┘
       ↑
     pivot

在這種情況下,樞軸為10。 從左側掃描, x指向50 ,因此它在那里停止。 另一方面, y停在10 好,所以我們交換它們。 我們得到:

x=0 y=2
┌──┬──┬──┬──┬──┬──┐
│10│30│50│40│20│60│
└──┴──┴──┴──┴──┴──┘
       ↑
     pivot

但是,等等,您只交換了數據! 變量pivot仍指向第三個Node 現在,我們不再繼續與10進行比較,而是與替換第三個節點中的數據的50進行比較

這使y停在1x移至2 因此,該列表被錯誤地划分為遞歸。 它應該分為

┌──┐┌──┬──┬──┬──┬──┐
│10││30│50│40│20│60│
└──┘└──┴──┴──┴──┴──┘

但是現在它分為:

┌──┬──┐┌──┬──┬──┬──┐
│10│30││50│40│20│60│
└──┴──┘└──┴──┴──┴──┘

因此,您應該做的是將數據透視表數據保留在局部變量中,而不是對pivot.data進行測試:

    Node pivot = findByIndex((low + high) / 2);
    int pivotData = pivot.data;
    int x = low, y = high;

    while (x <= y) {
        while (findByIndex(x).data < pivotData) {
            x++;
        }

        while (findByIndex(y).data > pivotData) {
            y--;
        }

話雖這么說,你的算法是非常低效

每次需要查找一個項目時,都從列表的開頭掃描到該項目。 對於每個findByIndex()這會將O(n)添加到算法的復雜性中。 listSize()的調用效率也不高,但至少只調用一次。 通過按照您的方式執行findByIndex() ,可以消除應該給您O(n log n)的遞歸調用的全部效果。 您甚至在交換內使用findByIndex()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM