在學習左神的演算法課,對快速排序有了更多的理解,在此記錄,以備後查
描述:快排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 遍歷陣...