[英]infinite loop in quicksort java
我嘗試實現一個快速排序算法,但是當我運行我的代碼時,它給了我一個無限循環,我不明白,我在代碼中的分區方法中犯了錯誤:
public static int partition(int[] a, int p, int r)
{
int x = a[p];
int i = p;
int j = r + 1;
while(true)
{
while(a[i] < x)
{
i++;
if (i == r) break;
}
while(x > a[j])
{
j--;
if (j == p) break;
}
if (i >= j) break;
int tmp = a[i];
a[i] = a[j];
tmp = a[i];
}
int exch = a[p];
a[p] = a[j];
exch = a[p];
return j;
}
此代碼的輸入數據:
private static int[] array;
private static Scanner sc = new Scanner(System.in);
public static void main(String[] args){
int n, m;
n = sc.nextInt();
array = new int[n+1];
int i,j;
for (i = 0; i != array.length-1; i++)
array[i] = sc.nextInt();
for (j = 0; j !=array.length-1; i++)
System.out.print(array[j]);
quickSort(array,0,array.length);
}
嘗試
a[j] = exch;
代替
exch = a[p];
和相同的bug - 感謝@Namer和@Zhuinden - 在你的代碼中:
int tmp = a[i];
a[i] = a[j];
tmp = a[i];
感謝@DeepanshuBedi, Java中的Quicksort - Tutorial描述了算法。 它有
i++;
j--;
在循環中交換之后。
此外,該函數預計是遞歸的:
if (low < j)
quicksort(low, j);
if (i < high)
quicksort(i, high);
而不是你的第二次交換。
我建議你從那個頁面復制代碼 - 你的代碼並不像我那樣快速。
您正在實施Quicksort算法的Cormen算法版本 。 他的版本是這樣的(沒有提到版權信息,這可以通過簡單的谷歌搜索找到):
你的版本幾乎全部錯過了。 例如,在前兩行:
int x = a[p]; //Should be a[r]
int i = p; //Should be p-1
再次檢查算法的每一步,並且只有在您真正理解算法如何重新編寫正確的函數之后。
你的quicksort函數也應該是遞歸的,我希望你知道這意味着什么 。
提示:有兩個函數,一個是遞歸的( quickSort
),另一個只有一個for循環( partition
)。
編輯:我從書中拿了錯誤的快速排序算法,對不起。 正確的,你正在使用的那個,如下:
您仍在使用一些非常基本的錯誤來實現它。 以下是最明顯的一些:
您正在使用while
循環而不是do-until (do-while in Java)
循環,這是非常不同的 。
你正在混合這兩種算法,交換(當我的第一條評論指出錯誤時)兩次在Hoare-Partition中只進行一次的值。
你不需要if (i >= j) break;
和if (i == r) break;
循環結束條件,因為,對於算法的構造,它們永遠不會發生(如果你使用a[i] < x
作為斷開條件或者a[i] >= x
作為允許條件)。 這表明您沒有完全理解算法的工作原理。
int i = p; //Should be p-1
int i = p; //Should be p-1
還是錯的。
再次,檢查算法的每一步並糾正它,你就在路上! :)
更新:我已嘗試使用上面的更正的Hoare分區和輸入int[] a = {13,19,9,5,12,8,7,4,11,2,6,21};
每次交換之后(順便說一下這是(a)書中問題的答案):
[6, 19, 9, 5, 12, 8, 7, 4, 11, 2, 13, 21]
[6, 13, 9, 5, 12, 8, 7, 4, 11, 2, 19, 21]
[6, 2, 9, 5, 12, 8, 7, 4, 11, 13, 19, 21]
[4, 2, 9, 5, 12, 8, 7, 6, 11, 13, 19, 21]
[4, 2, 6, 5, 12, 8, 7, 9, 11, 13, 19, 21]
[4, 2, 5, 6, 12, 8, 7, 9, 11, 13, 19, 21]
[2, 4, 5, 6, 12, 8, 7, 9, 11, 13, 19, 21]
[2, 4, 5, 6, 11, 8, 7, 9, 12, 13, 19, 21]
[2, 4, 5, 6, 9, 8, 7, 11, 12, 13, 19, 21]
[2, 4, 5, 6, 7, 8, 9, 11, 12, 13, 19, 21]
這僅僅是為了檢查算法是否有效(可能是打印錯誤可能導致無限循環)。
快速排序的基礎知識嘗試這可以解決您的問題。
if (i <= j) {
tmp = a[i];
a[i] = a[j];
a[j] = tmp;
i++;
j--;}
**int exch = a[p];
a[p] = a[j];
a[p] = exch;**
編輯了你的代碼。 我建議你使用for-loop。
public static int partition(int[] a, int p, int r)
{
int x = a[p];
int i = p;
int j = r + 1;
while(true)
{
while(a[i] < x)
{
i++;
if (i == r) break;
}
while(x > a[j])
{
j--;
if (j == p) break;
}
if (i <= j) {
tmp = a[i];
a[i] = a[j];
a[j] = tmp;
i++;
j--;}
**int exch = a[p];
a[p] = a[j];
a[p] = exch;**
return j;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.