我一直在研究快速排序幾個小時,並且對選擇一個樞軸值感到困惑。數據透視值是否需要存在於數組中?如何在QuickSort中選擇樞軸值?
例如,如果數組是1,2,5,6,我們可以使用值3還是4作爲支點?
我們使用pivot的位置來將數組分割成子數組,但我們對將數組左側的值和右側的值> 5的數值移動後的樞軸位置有些困惑?
7,1,5,3,3,5,8,9,2,1
我拼命地跑乾的算法中與樞軸5和具有以下結果出來:
1,1,5,3,3,5,8,9,2,7
1,1,5,3,3,5,8,9,2,7
1,1,5,3,3,5,8,2,9,7
我們可以看到,值2仍然沒有在正確的位置。我究竟做錯了什麼?對不起,如果這是一個愚蠢的問題。
我想出了以下代碼,但它只在pivot = left時才起作用,我不能使用隨機數據透視表。
template <class T>
void quickSort(vector <T> & arr, int p, int r, bool piv_flag) {
if (p < r) {
int q, piv(p); counter++;
//piv = ((p + r)/2); doesn't work
q = partition(arr, p, r, piv);
quickSort(arr, p, q - 1, piv_flag); //Sort left half
quickSort(arr, q + 1, r, piv_flag); //Sort right half
}
return;
}
int partition(vector <T> & arr, int left, int right, int piv) {
int i{ left - 0 }, j{ right + 0 }, pivot{ arr[piv] };
while (i < j) {
while (arr[i] <= pivot) { i++; }
while (arr[j] > pivot) { j--; }
if (i < j) (swap(arr[i], arr[j]));
else {
swap(arr[j], arr[piv]);
return j;
}
}
}
謝謝。
感謝您的迴應,我實際上無法理解如何處理重複。我正在使用以下算法進行分區,但只有在樞軸位置=左側時才起作用。這基本上意味着我不能使用完全隨機的樞軸位置。 int int {int left(0),j {right + 0},pivot {arr [piv]}; int分區(向量&arr,int left,int right,int piv){ \t \t while(i pivot){j--; }(i
Anon
感謝您的詳細解答。你在這裏做的是將樞軸轉移到左邊,然後運行快速排序算法,但是我們可以簡單地選擇最左邊的元素作爲樞軸位置,沒有選擇隨機樞軸位置的優勢。 – Anon
其實,優勢依然存在。您不是選擇最左邊的元素,而是選擇任何您想要的元素,因此您可以利用選擇任何元素的優點來實現類似大小的分組。與最左邊元素的交換隻是在一個平滑循環中從索引left + 1到index right遍歷向量。 – ilim