我在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;
}
答案 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
停在1
,x
移至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()
!