演算法學習筆記 快速排序

2021-10-07 06:45:11 字數 3976 閱讀 1299

在學習左神的演算法課,對快速排序有了更多的理解,在此記錄,以備後查

描述:快排1.0是基於單個支點進行遞迴操作。大體來講,是選擇陣列arr中的某乙個數作為支點pivot,經過一通操作(一般叫partition),使得左邊的數均小於等於pivot,右邊的數均》pivot,如此一來,pivot就待在了自已排好序的位置。然後再對左邊和右邊分別做同樣的操作,就完成了整個陣列的排序

**:

/**

* 快速排序 1.0

* @param arr

* @param left

* @param right

*/public

static

void

quicksort1

(int

arr,

int left,

int right)

//進行partition操作,返回支點的位置

int pivot =

partition1

(arr, left, right)

;//對支點左邊快排

quicksort1

(arr, left, pivot -1)

;//對支點右邊快排

quicksort1

(arr, pivot +

1, right);}

/** * 以arr[right]作為支點值,j為右半邊的

* 左邊界,curr指向當前待判斷的數

* @param arr

* @param left

* @param right

*/private

static

intpartition1

(int

arr,

int left,

int right)

else

}swap

(arr, right, j)

;return j;

}

描述:

快排2.0仍然是基於單個支點的遞迴,不同於1.0之處,在於陣列中可能有多個值跟支點pivot相等,每次partition,可以把陣列分成小於pivot、等於pivot、大於pivot這三部分,避免跟pivot相等的值重複參與partition

**:

/**

* 快速排序 2.0

* @param arr

* @param left

* @param right

*/public

static

void

quicksort2

(int

arr,

int left,

int right)

//進行partition操作,返回支點的位置

int[

] leftright =

partition2

(arr, left, right)

;//對支點左邊快排

quicksort2

(arr, left, leftright[0]

-1);

//對支點右邊快排

quicksort2

(arr,leftright[1]

+1, right);}

/** * 以arr[right]作為支點值,i為左半邊的有邊界,j為右半邊的

* 左邊界,curr指向當前待判斷的數

* @param arr

* @param left

* @param right

* @return

*/private

static

int[

]partition2

(int

arr,

int left,

int right);}

int i=left-

1, j = right, curr = left;

while

(curr < j)

else

if(arr[curr]

==arr[right]

)else

}swap

(arr, right, j)

;return

newint

;}

描述:

快排3.0相比於2.0,增加了乙個隨機因子,即不再固定選擇arr[right]作為支點,而是在arr中隨機選擇乙個。目的是為了減少最壞情況(效能退化為o(n2))發生的概率。

**:

/**

* 快速排序 3.0

* @param arr

* @param left

* @param right

*/public

static

void

quicksort3

(int

arr,

int left,

int right)

//隨機選擇乙個,交換到arr[right]

swap

(arr,right,l+

(int

)math.

random()

*(right-left+1)

);//進行partition操作,返回支點的位置

int[

] leftright =

partition2

(arr, left, right)

;//對支點左邊快排

quicksort2

(arr, left, leftright[0]

-1);

//對支點右邊快排

quicksort2

(arr,leftright[1]

+1, right);}

/** * 以arr[right]作為支點值,i為左半邊的有邊界,j為右半邊的

* 左邊界,curr指向當前待判斷的數

* @param arr

* @param left

* @param right

* @return

*/private

static

int[

]partition2

(int

arr,

int left,

int right);}

int i=left-

1, j = right, curr = left;

while

(curr < j)

else

if(arr[curr]

==arr[right]

)else

}swap

(arr, right, j)

;return

newint

;}

描述:

給定乙個陣列arr,和乙個數num,請把小於num的數放在陣列的左邊,等於num的數放在陣列的中間,大於num的數放在陣列的右邊。

要求額外空間複雜度o(1),時間複雜度o(n)

思路:和快速排序2.0的一次partition操作基本一致,略有不同之處在於,num不是陣列arr中的數,因而不需要arr[right]作為支點,右半邊的左邊界初始值應該從arr.length開始

**:

/**

* 荷蘭國旗問題

* @param arr

* @return

*/private

static

int[

]netherlandflag

(int

arr,

int num)

int less=-1

,more=arr.length;

int curr=0;

while

(curr < more)

else

if(arr[curr]

==num)

else

}return

newint

;}

演算法學習筆記 1 快速排序

快速排序是一種二分的排序演算法,這種演算法的誕生來自於對有序陣列的觀察。我們假設有以下陣列 1,2,3,4,5,6,7,8,9 這是乙個已經按照從小到大排序完畢的有序陣列。觀察以上陣列,取其中間數5,我們可以發現5以左的數1,2,3,4均比5小,5以右的數6,7,8,9均比5大。我們以5為分界線將陣...

演算法學習 快速排序

快速排序 分治演算法 const int n 1e6 10 int a n a 待排序陣列,l 排序陣列的起始下標,r 排序陣列的結束下標 void quick sort int a,int l,int r 遞迴的終止條件 int x a l 選取排序的比較物件 int i l 1 設定排序的左指標...

演算法學習 快速排序

1 基本思想 取待排序陣列第乙個數作為參照數,建立left和right陣列,left儲存小於參照數的陣列集合,right儲存大於參照數的陣列集合,然後分別對left和right進行遞迴呼叫排序。2 舉例 11,2,3,43,23,5,6,9,10 取任意的乙個數為基準數 temp arr 0 遍歷陣...