快速排序
講解的十分生動形象
維護乙個指標lo,維護乙個指標hi,初始時lo指向陣列的第乙個元素,hi指向陣列的最後乙個元素。
對於快速排序來說其核心有如下幾點
1. 選取乙個元素(一般為陣列的第乙個元素)作為基準,可以生動的想象在基準元素上挖了乙個坑,把基準元素挖了出來,並移植給了臨時變數x
2. 既然將基準元素挖坑並取走那還需要把這個坑給填上,所以就從陣列尾端向前遍歷,直到遇到第i個位置的元素小於基準元素x,這時候就可以把第i個位置的元素挖走,並放到之前被挖走元素的位置上。(挖走只是形象的說法,其實該位置元素並沒有物理上的變化,只是覆蓋的過程)
3. 當經過第2步後第一步被挖走的位置已經被第二步挖來的元素填充,所以可以繼續向後移動lo指標,直到遇到乙個j位置使得j位置的元素大於x元素,將j位置挖走,放到第二步中空缺的位置處。
4. 直到lo和hi重合完成一次遍歷,將x元素值填到此時的lo指標指向的位置,因為如果把上述步驟想象成挖坑填坑的話,當lo與hi重合的位置一定是最後乙個需要填坑的位置,並且lo之前的值都小於等於x,之後的值都大於等於x
5. 遞迴執行。
public
void
sort(int nums,int lo,int high)
int x=nums[lo];
int begin=lo;
int end=high;
while(lowhile(lo=x)
if(lowhile(loif(lo1);
sort(nums,lo+1,end);
}
三向切分的快排
快速排序的改進一般基於如下兩點:
1. 當陣列的規模較小時,快速排序的效率不如插入排序,因此當遞迴到陣列規模較小時可以進行插入排序
修改**為:
將:
if(lo>=high)
修改為:
if(hi<=lo+m)
2.對於存在大量重複元素的時候,可以採用三向切分的方式
其主要過程如下:
1. 從左到右遍歷一次,維護乙個指標lt,使得a[lo,lt-1]的元素都小於v,乙個指標gt,使得a[gt+1,hi]的元素都大於v,維護乙個指標i,使得a[lt,i-1]的元素都等於v,a[i,gt]的元素為還未參加排序的元素
如果a[i]
public void sort(int a,int lo,int hi)
intlt=lo;
int i=lo+1;
intgt=hi;
intx=a[lo];
while(i<=gt)
if(a[i]>x)
if(a[i]==x)
}sort(a,lo,lt-1);
sort(a,gt+1,lt);
}
三向切分的快速排序
在排序的實際應用中,經常會出現大量重複元素的陣列,比如生日排序。而在這種情況下,快速排序仍有巨大的改進空間,如 乙個元素重複的子陣列就不需要繼續排序了,但演算法卻仍會將它繼續切分為更小的陣列,三向切分的快速排序 正是基於此對 快速排序 的作出的改進。三向切分的快速排序將陣列切分為三部分,分別對應小於...
快速排序的一種優化演算法(三向切分)
快速排序 時間複雜度o n logn 最壞情況為o n 2 空間複雜度o 1 但是堆疊深度一般情況為o logn 最壞情況為o n 快速排序實現 partition劃分演算法 int partition seqlist r,int i,int j endwhile r i pivot 基準記錄已被最...
C語言 三向字串快速排序
在將字串陣列排序時,根據首字母進行三向切分,然後 遞迴地 將得到的三個子陣列排序 乙個含有所有首字母小於切分字元的字串子陣列,乙個含有所有首字母等於切分字元的字串的子陣列 排序時忽略它們的首字母 乙個含有所有首字母大於切分字元的字串的子陣列。實現 include include include in...