Quicksort在java中实现linkedlist

时间:2014-12-14 18:17:37

标签: java data-structures quicksort

我在java中编写了自己的链表并且它没有问题,但是当我想要实现快速排序算法时,它会产生奇怪的输出,即;

分别列出元素= 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;
}

1 个答案:

答案 0 :(得分:1)

以下是发生的事情:

首先,您的列表是:

┌──┬──┬──┬──┬──┬──┐
│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 数据保存在局部变量中,而不是针对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()