三向切分快速排序
我們知道快速排序的應(yīng)用非常廣泛,也許你可以非常熟練的可以寫出一個(gè)快速排序,在大多數(shù)情況下快速排序是可以適用的,但是快速排序還有一個(gè)改進(jìn)的算法稱為三向切分快速排序,它是快速排序的一個(gè)變種,尤其適合在數(shù)據(jù)大量重復(fù)的情況下使用,它對(duì)快速排序性能的提升程度取決于重復(fù)數(shù)字的多少,平均時(shí)間復(fù)雜度介于N和NlogN之間。
在學(xué)習(xí)三向切分快速排序之前,我們先來(lái)了解一下 E.W.Dijlstra(Dijkstra最短路徑算法的發(fā)明者)曾經(jīng)提出的一個(gè)關(guān)于荷蘭國(guó)旗的問(wèn)題:
荷蘭國(guó)旗包含三種顏色:紅、白、藍(lán)。有這三種顏色的球,算法的目標(biāo)是將這三種球按荷蘭國(guó)旗顏色順序正確地排列,即紅白藍(lán)的順序排序。
這里我們使用0,1,2來(lái)表示紅、白、藍(lán)。要求時(shí)間復(fù)雜度為O(n);
例如:
解決方法如下:
public void sortColors(int[] nums) {int zero = -1, one = 0, two = nums.length;while (one < two) {if (nums[one] == 0) {swap(nums, ++zero, one++);} else if (nums[one] == 2) {swap(nums, --two, one);} else {++one;}} }private void swap(int[] nums, int i, int j) {int t = nums[i];nums[i] = nums[j];nums[j] = t; }可以看到它使用了三個(gè)指針,分別代表三個(gè)不同的顏色。one指向未知的顏色,之后判斷,如果是紅色則和zero交換,如果是藍(lán)色則和two交換。最后數(shù)組中的情況如下:
其實(shí)三向切分快速排序基本上也是這個(gè)思想,如下:
對(duì)比上面就是<V為紅色,=V為白色,>V為藍(lán)色。轉(zhuǎn)換為代碼就是:
最后,在編寫三向切分快速排序的時(shí)候要尤其注意數(shù)組下標(biāo)的正確與否,這里的下標(biāo)寫法,我們使用的是上面解決荷蘭國(guó)旗的下標(biāo)寫法。
總結(jié)
- 上一篇: 使用Fork/Join框架优化归并排序
- 下一篇: 一个简单的因数分解java代码