想要變優(yōu)秀,順其自然是不可能的
你需要做很多,花很多時(shí)間苟径,忍耐并且堅(jiān)持。
快速排序痛黎,簡(jiǎn)稱快排,也是初級(jí)面試?yán)锩姹粏柕阶疃嗟呐判蛩惴ü伟桑谄胀ㄊ褂们闆r下(數(shù)據(jù)基本無(wú)序湖饱,數(shù)據(jù)量n巨大),相對(duì)于直接插入排序杀捻,簡(jiǎn)單選擇排序井厌,冒泡法排序,快速排序的效率都會(huì)更優(yōu)。這是由冒泡排序改進(jìn)的算法旗笔,也是一種基于交換排序的算法,但是不同于冒泡排序拄踪,冒泡排序每次只比較交換相鄰的兩個(gè)元素蝇恶,每次只消除兩個(gè)元素之間的逆序,但是快速排序通過兩個(gè)相鄰或者不相鄰的元素的交換惶桐,能消除多個(gè)逆序撮弧,極大地加快排序的速度。
下面是每次進(jìn)行冒泡排序時(shí)的模式姚糊,這個(gè)過程中贿衍,因?yàn)槊看沃粫?huì)交換相鄰兩個(gè)元素的位置,所以只會(huì)修改這兩個(gè)元素的順序
相對(duì)于快速排序救恨,一次可能消除多個(gè)逆序的情況贸辈,隨機(jī)選擇一個(gè)記錄anchor(一般選擇第一個(gè)元素),通過一趟排序把比anchor大的值放到右子表肠槽,比anchor小的值放到左子表擎淤,再對(duì)左右子表使用同樣的方式進(jìn)行劃分,直到每個(gè)子表都只有一個(gè)元素秸仙。
對(duì)于每一趟循環(huán)嘴拢,首先設(shè)定low和high指向左右兩個(gè)邊界:
1、比較右邊界high和anchor的大小寂纪,如果high大于anchor的值席吴,那么high--,如果是小于anchor的值捞蛋,那么交換anchor和high的位置孝冒,如果找到了比anchor小的值,那么到達(dá)第2步
2拟杉、比較左邊界low和anchor的大小迈倍,如果low小于anchor的值,那么low++捣域,如果是大于anchor的值啼染,那么交換anchor和low的位置,返回第1步
3焕梅、重復(fù)第1步和第2步迹鹅,直到low == high為止。
剛好碰巧第一個(gè)元素就是整個(gè)數(shù)組最小的贞言,這里我們也看到了斜棚,要是元素最小的話,那么效率就跟普通的冒泡排序差不多一樣了。如果我們的序列一開始就是基本有序的弟蚀,快速排序算法(一次交換消除多個(gè)元素的逆序)的優(yōu)勢(shì)就不明顯了蚤霞。
private static int Partition(int[] num,int low,int high){
int anchor = num[low]; //用第一個(gè)元素作為anchor
//當(dāng)low == high的時(shí)候退出循環(huán)
while(low <high){
// 如果anchor的值小于high,high左移
while(low <high && anchor < num[high]) high--;
num[low] = num[high];
// 如果anchor的值大于high义钉,low右移
while(low < high && anchor >= num[low]) low++;
//當(dāng)前的low值大于anchor昧绣,讓low位置的值移動(dòng)anchor的位置
num[high] = num[low];
}
//跳出循環(huán)時(shí),anchor不再移動(dòng)
num[high] = anchor;
return high;
}
private static void QuickSort(int[] num,int low,int high){
if (low < high) {
//第一趟排序后anchor的位置
int index = Partition(num, low, high);
QuickSort(num, low, index - 1);
QuickSort(num, index+1, high);
}
}
算法特點(diǎn)
最好的情況是待排序的集合無(wú)序捶闸,最壞情況帶排序集合基本有序夜畴,平均情況下的時(shí)間復(fù)雜度為O(nlogn),空間復(fù)雜度最好情況下為O(logn)删壮,最壞情況為O(n)贪绘,適用于初始記錄無(wú)序,n較大的情況央碟。