排序算法系列:奇偶排序演算法
阿新 • • 發佈:2019-01-26
概述
在上一篇中我們說到了氣泡排序的原理及實現詳解。氣泡排序是一種交換排序,本文還是接著上一講,說說另一種交換排序演算法——奇偶排序。
版權說明
目錄
奇偶排序演算法
奇偶排序實際上在多處理器環境中很有用,處理器可以分別同時處理每一個奇數對,然後又同時處理偶數對。因為奇數對是彼此獨立的,每一刻都可以用不同的處理器比較和交換。這樣可以非常快速地排序。
— 《Java資料結構和演算法》
演算法原理
我不太清楚有多少人跟我一樣,看到奇偶排序的第一感覺是,對陣列中的奇數列和偶數列分別進行排序,再使用類似歸併排序中的合併操作使整體有序。
不過,這裡的臆想並不是奇偶排序的思想,希望大家不要將上面的思路理解成奇偶排序。糾錯之後,讓我們來看看真正的奇偶排序是什麼樣的吧。
奇偶排序的核心是,以奇數列為基準和以偶數列為基準對整個陣列進行排序。而排序的元素只有兩個,基準元素和其右側相鄰的一個元素。原理可參見下面的演算法原理圖。
演算法原理圖
演算法步驟
- 選取所有奇數列的元素與其右側相鄰的元素進行比較,將較小的元素排序在前面;
- 選取所有偶數列的元素與其右側相鄰的元素進行比較,將較小的元素排序在前面;
- 重複前面兩步,直到所有序列有序為止。
演算法可行性證明
在前一篇氣泡排序演算法,我們並沒有演算法可行性證明這一個點,原因是因為從它的原理或是過程圖中,我們可以從直觀上理解到它的可行性。而現在要說的奇偶排序則不一樣了,我們從上面的原理圖,無法得出此演算法就一定可行,所以在此給出一些比較簡單地演算法可行性證明過程。證明過程如下:
- 我們使用奇數排序+偶數排序,可以覆蓋陣列中的所有元素;
- 針對一組操作(奇數排序+偶數排序),陣列中的所有元素形成鏈狀;2
- 假定一個元素為a[i],我們可以通過N次的奇偶交換排序,將a[i]沿著上面的鏈狀結構移動到合適的位置;
- 通過第3步的分析,我們可以將陣列中的所有元素移動到合適的位置,從而使整體有序。
演算法過程圖
演算法實現
private void core(int[] array) {
int arrayLength = array.length;
boolean oddSorted = false;
boolean evenSorted = false;
while (!oddSorted || !evenSorted) {
int base = 0;
oddSorted = true;
evenSorted = true;
for (int i = base; i < arrayLength - 1; i += 2) {
if (array[i] > array[i + 1]) {
ArrayUtils.swap(array, i, i + 1);
oddSorted = false;
}
}
base = 1;
for (int i = base; i < arrayLength - 1; i += 2) {
if (array[i] > array[i + 1]) {
ArrayUtils.swap(array, i, i + 1);
evenSorted = false;
}
}
}
}
演算法複雜度分析
排序方法 | 時間複雜度 | 空間複雜度 | 穩定性 | 複雜性 | ||
平均情況 | 最壞情況 | 最好情況 | ||||
奇偶排序 | O(nlog2n) | O(nlog2n) | O(n) | O(1) | 穩定 | 較簡單 |