快速排序是八大排序算法之一,運(yùn)用也是相當(dāng)廣泛。快速排序是分治思想的一種體現(xiàn),分治就是將一個(gè)規(guī)模為N的問(wèn)題分解成K個(gè)規(guī)模較小的問(wèn)題,這些子問(wèn)題相互獨(dú)立且與原問(wèn)題性質(zhì)相同。求出子問(wèn)題的解,就可得到原問(wèn)題的解。
比如給定一組數(shù)據(jù)[31, 68, 45, 90, 23, 39, 54, 12, 87, 76],我們用快速排序的思想來(lái)對(duì)這組數(shù)據(jù)進(jìn)行排序。
現(xiàn)在我們使用圖解來(lái)分析它的排序步驟:
(1)第一步:定義兩個(gè)指針low和high,low指針指向數(shù)組的第一個(gè)位置,high指針指向數(shù)組中的最后一個(gè)位置。并且用一個(gè)temp變量來(lái)存儲(chǔ)第一個(gè)位置的數(shù)據(jù),即temp=31。
(2)第二步:我們定義一個(gè)指針移動(dòng)方向,先從右往左移動(dòng),即先移動(dòng)high指針。先用high指針上的數(shù)據(jù)和temp進(jìn)行比較,如果high指針上的數(shù)據(jù)大于temp,那就一直往左邊移動(dòng)high指針。直到high指針上的數(shù)據(jù)比temp小時(shí),high指針才停止移動(dòng)。
(3)第三步:現(xiàn)在出現(xiàn)了high指針上的數(shù)據(jù)小于了temp,即array[high] < temp,即(12 < 31)。我們就要把high指針指向的數(shù)據(jù)放到low指針的位置上; high指針停止移動(dòng),然后改變指針移動(dòng)方向,low指針向右移動(dòng)1位。
(4)第四步:low指針向右移動(dòng)過(guò)程中如果array[low]>temp,就把low上面對(duì)應(yīng)的數(shù)據(jù)放到array[high]上;并且low指針不動(dòng),改變指針移動(dòng)方向,high指針向前移動(dòng)一位。
(5)根據(jù)這樣的規(guī)律一直找下去,直到兩個(gè)指針重合,把temp的數(shù)據(jù)放到重合位置上面。
(5)這樣一輪下來(lái)之后,我們就針對(duì)放置temp數(shù)據(jù)的位置的左右兩邊進(jìn)行快速排序,即使用遞歸。
說(shuō)了這么多我也不知道清沒(méi)清楚,最后還是回到代碼上來(lái)處理:
//begin和end是傳入數(shù)組array的頭尾兩個(gè)下標(biāo)
public static void quickSort(int[] array,int begin,int end){
if(end <= begin){
return;
}
//step1:定義兩個(gè)指針下標(biāo)指向數(shù)組兩端,并把開(kāi)始指針處的數(shù)據(jù)存儲(chǔ)起來(lái)
int low = begin;
int high = end;
int temp = array[begin];
//step2:定義兩個(gè)指針的移動(dòng)
boolean direction = true;
L1:
while(low < high){
if(direction) { //高位指針向左移動(dòng)
for (int i = high; i > low; i--) {
if (array[i] <= temp) {
array[low++] = array[i]; //把這個(gè)小的數(shù)放到低位指針的位置,并且低位指針向右移動(dòng)1位
high = i; //并修改高位指針的位置,讓其放置在滿(mǎn)足if條件的i上
direction = !direction; //改變指針移動(dòng)
continue L1;
}
}
high = low; //最后兩個(gè)位置重合即可跳出循環(huán)
}else{
for(int i=low;i<high;i++){
if(array[i] >= temp){
array[high--] = array[i];
low = i;
direction = !direction;
continue L1;
}
}
low = high;
}
}
//step3:把temp放到兩個(gè)指針重合的位置
array[low] = temp;
//array[high] = temp;
//step4:把放置temp數(shù)據(jù)的左右兩邊繼續(xù)進(jìn)行快速排序,這很類(lèi)似二叉樹(shù)的前序遍歷
quickSort(array,begin,low-1);
quickSort(array,low+1,end);
}
快速排序的應(yīng)用場(chǎng)景:源數(shù)據(jù)是數(shù)據(jù)量大并且是順序存儲(chǔ)結(jié)構(gòu)使用快速排序效率最高。
短處:
(1)數(shù)據(jù)中有大量重復(fù)數(shù)據(jù)的時(shí)候性能不好;
(2)數(shù)據(jù)是鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)的時(shí)候,性能下降嚴(yán)重。
那數(shù)據(jù)是鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)的時(shí)候我們用什么排序呢?下篇文章再進(jìn)行分析。
小白筆記,如有錯(cuò)誤歡迎指正!