快速排序的簡單分析

2021-07-24 17:22:44 字數 3948 閱讀 4082

快速排序有很多版本,這裡給出一種基礎版本和一種典型加強版本,即三數取中版本.

public

class

quicksort

private

static

void

quicksort(int a, int left, int right)

int cutoff = partition(a, left, right,right);

quicksort(a, left, cutoff - 1);

quicksort(a, cutoff + 1, right);

}private

static

intpartition(int a, int left,int right,int pivot)

if (leftptr >= rightptr) else

}exchange(a,leftptr,right);

return leftptr;

}private

static

void

exchange(int a ,int x, int y)

}

public

class

quicksort_median3

private

static

void

quicksort(int a, int left, int right)

int median=median3(a,left,right);

int cutoff = partition(a, left, right, median);

quicksort(a, left, cutoff - 1);

quicksort(a, cutoff + 1, right);

}private

static

void

manualsort(int a,int left, int right)

if (size == 2)

} else

if ((a[left] > right))

if (a[right - 1] > right) }}

private

static

intpartition(int a, int left, int right, int pivot)

if (leftptr >= rightptr) else

}exchange(a,leftptr,right-1);

return leftptr;

}private

static

intmedian3(int a,int left, int right)

if (a[left] > a[right])

if (a[center] > a[right])

exchange(a,center,right-1);

return right-1;

}private

static

void

exchange(int a ,int x, int y)

}

快速排序的難點不在於理解,而在於**實現.

核心步驟是:

1. 指定某個值,

2. 把陣列中所有小於這個數的數放在左邊

3. 把陣列中所有大於這個數的數放在右邊

4. 對於左邊的陣列重複步驟12345

5. 對於右邊的陣列重複步驟12345

而在**中有很多細節需要注意.

基礎版快排

首先要有乙個驅動程式,穿入一左一右兩個指標

public

static

void

quicksort(int a)

直接選取最右的位置的值作為樞紐,寫出快排框架:

private

static

void

quicksort(int a, int left, int right)

int cutoff = partition(a, left, right,right);//以最右位為樞紐.

quicksort(a, left, cutoff - 1);

quicksort(a, cutoff + 1, right);

}

注意,此段程式為遞迴程式,所以引數必須為可變的.不能再內部指定left,right.

合格的遞迴應有恰當的跳出條件.左指標大於右指標的時候需要結束遞迴.

事實上partition方法承擔了大部分任務.它負責內部的跳躍交換,最後返回歸位後的樞紐位置.最後乙個引數是初始樞紐,直接給為right.

partition(a, left, right,right)

左遞迴,右遞迴.

quicksort(a, left, cutoff - 1);

quicksort(a, cutoff + 1, right);

接下來是分割程式.分割承擔了內部的跳躍任務,細節不太容易準確寫對.

private

static

intpartition(int a, int left,int right,int pivot)//右指標與樞紐比較,盡可能左移.由於先左移後比較,故只要right>0即可保證right-1>=0,不會左越界.最後落在小於等於pivot的位置.

if (leftptr >= rightptr) else

}exchange(a,leftptr,right);//樞紐歸位.

return leftptr;

}

三數取中版快排

三數分割法在選取樞紐的環節做了優化,使平均效率更高.雖然**量有所增加,但是反而使分割環節的細節好記了一些.

在基礎版中,選取樞紐的方法是直接任命right.而如果right並非約等於中值而是約等於最大值或最小值,將會有最差o(n^2)的時間複雜度.而三數分割法大大降低了這樣的可能性.

三數取中過程:

private

static

intmedian3(int a,int left, int right)

if (a[left] > a[right])

if (a[center] > a[right])

exchange(a,center,right-1);//最後把樞紐值置於倒數第二個位置.

return right-1;//返回樞紐位置.

}

分割過程:

private

static

intpartition(int a, int left, int right, int pivot)

if (leftptr >= rightptr) else

}exchange(a,leftptr,right-1);

return leftptr;

}

與基礎版類似,但是由於最左,最右,右倒2都已經被佔據且排好序,故在指定比較指標的時候要稍稍改變.另外,由於左右兩端都已經left<=pivotval<=right,所以內部while迴圈時無需再判斷邊界,一定不會越界.

當數值小於等於3的時候,為了效率要求,我們單獨為3個數寫出排序.

private

static

void

manualsort(int a,int left, int right)

if (size == 2)

} else

if ((a[left] > right))

if (a[right - 1] > right)

}}

簡單的快速排序

1 定義int left start,right end 再定義乙個標誌位 boolen flag true。2 在迴圈體中比較,只要left right,就進行比較。3 剛開始將最左邊數最為基準數basenumber arr left 將基準數basenumber逐一與右邊倒序比較,直到basen...

快速排序分析

1.開篇 終於還是忍不住要學習一下演算法啦,該面對的還是要面對,不能逃避,不能把已經會的技能忘掉,那是一種對生命的摧殘和不仁。不要怕,只要每天都在進步,水滴石穿,終有破雲見天日的時刻。感慨寫完了,回到正題,分析快速排序。2.原理 假設要排序的陣列是a 0 a n 1 首先任意選取乙個資料 通常選用陣...

快速排序分析

首先簡單描述一下快速排序 1.快速排序樹不穩定的 由於關鍵字的比較與交換是跳躍進行的 2.時間複雜度為o n logn 最好情況為n logn 若陣列基本有序為n n 3.空間複雜度為logn 主要是遞迴造成的棧空間的使用,最好情況,遞迴樹的深度為log2n,其空間複雜度也就為o logn 最壞情況...