快速排序與三向切分的快速排序

2021-08-15 01:25:55 字數 1440 閱讀 4448

快速排序

講解的十分生動形象

維護乙個指標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...