快速排序的原理:
選擇一個關鍵值作爲基準值。比基準值小的都在左邊序列(一般是無序的),比基準值大的都在右邊(一般是無序的)。一般選擇序列的第一個元素。
一次循環:從後往前比較,用基準值和最後一個值比較,如果比基準值小的交換位置,如果沒有繼續比較下一個,直到找到第一個比基準值小的值才交換。
找到這個值之後,又從前往後開始比較,如果有比基準值大的,交換位置,如果沒有繼續比較下一個,直到找到第一個比基準值大的值才交換。
直到從前往後的比較索引>從後往前比較的索引,結束第一次循環,此時,對於基準值來說,左右兩邊就是有序的了。
接着分別比較左右兩邊的序列,重複上述的循環。
實現代碼:
/**
* 快速排序<br/>
* <ul>
* <li>從數列中挑出一個元素,稱爲“基準”</li>
* <li>重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。在這個分割之後,
* 該基準是它的最後位置。這個稱爲分割(partition)操作。</li>
* <li>遞歸地把小於基準值元素的子數列和大於基準值元素的子數列排序。</li>
* </ul>
*
* @param numbers 待排序數組
* @param low 數組最小下標
* @param high 數組最大下標
*/
public void quickSort(int[] numbers, int low, int high) {
int start = low;
int end = high;
int key = numbers[low];
while (end > start) {
// 從後往前比較
while (end > start && numbers[end] >= key) // 如果沒有比關鍵值小的,比較下一個,直到有比關鍵值小的交換位置,然後又從前往後比較
end--;
if (numbers[end] <= key) {
int temp = numbers[end];
numbers[end] = numbers[start];
numbers[start] = temp;
}
// 從前往後比較
while (end > start && numbers[start] <= key)// 如果沒有比關鍵值大的,比較下一個,直到有比關鍵值大的交換位置
start++;
if (numbers[start] >= key) {
int temp = numbers[start];
numbers[start] = numbers[end];
numbers[end] = temp;
}
// 此時第一次循環比較結束,關鍵值的位置已經確定了。左邊的值都比關鍵值小,右邊的值都比關鍵值大,但是兩邊的順序還有可能是不一樣的,進行下面的遞歸調用
}
// 遞歸
if (start > low) {
// 左邊序列。第一個索引位置到關鍵值索引-1
quickSort(numbers, low, start - 1);
}
if (end < high) {
// 右邊序列。從關鍵值索引+1到最後一個
quickSort(numbers, end + 1, high);
}
}
在序列中元素很少時,快速排序效率將比較低,不如插入排序,因此一般在序列中元素很少時使用插入排序,這樣可以提高整體效率。