熵最佳排序
package com.concurency.sort;
import edu.princeton.cs.algs4.stdout;
import edu.princeton.cs.algs4.stdrandom;
// 快速排序
public
class
quick
public
static
void
sort
(comparable[
] a,
int low,
int high)
// 分割槽,以j為分界點,左邊都比a[j]小,右邊都比a[j]大
// 如果j 為 high?如何處理?如果j為low,如何處理 ----> filter
int j =
partition
(a,low,high)
;// 將左邊再次分割槽
sort
(a,low,j-1)
;// 將右邊再次分割槽
sort
(a,j+
1,high);}
private
static
intpartition
(comparable[
] a,
int low,
int high)
}// 從 high 開始一直找到比j小的數
// 為什麼j=high,這裡使用j--會不行?
// 這裡不能使用j--,
// 原因是j參與後面的運算,如果使用j--,比較的是j,而後面參與運算的是j--,這樣直接會產生錯誤,j必須使用最終值
// 如果<=v,說明當前值不符合預期,需要交換,如果vwhile
(less
(v,a[
--j]))
}// 最合適的位置可能比v大,也可能比v小,也可能等於v,
// 如果向後方推進的位置i>=j,說明i,j位置發生了交錯,錯過了最合適的位置,在交換已經變得毫無意義。
if(i >= j)
break
;// 將比v大的和比v小的交換位置
exchange
(a,j,i);}
// 最終匯聚的位置是v最合適的位置
// 為什麼取j,不取i????是什麼決定的v最合適的位置
// 解答:左邊小,右邊大,v的位置沒有變,把小的換到左邊,把大的換到右邊,
// 因為從low開始,如果和i交換,左邊會呈現亂序
/* * 原序:3 4 5 1 2
** 假設已經拍好了,等待放入合適位置
* 理想狀態: v = 3 ,交換後 3 2 1 5 4 此時 i = 3,j = 2
* 如果此時 選 i,即 5 2 1 3 4 ,很明顯,依然是亂序
* 如果此時 選 j,即 1 2 3 5 4 ,完全符合預期**
* 另一種設想,如果v選high
** v = 2,**會有所不同,比如向前推進變為high - 1 開始,而向後推進變為low開始
** 交換後: 1 4 5 3 2 i = 1,j=0
** 選 i 交換 1 2 5 3 4,完全符合預期、
* 選 j 交換 2 4 5 3 1,不符合預期。
** 所以,選i,還是選j,取決於v的取值**
* */
exchange
(a,j,low)
;return j;
}private
static
boolean
less
(comparable a,comparable b)
private
static
void
exchange
(comparable[
] a,
int i,
int j)
protected
static
void
show
(comparable[
] a)
stdout.
println()
;}public
static
void
main
(string[
] args)
}
public
static
void
sort
(comparable[
] a,
int low,
int high)
// 分割槽,以j為分界點,左邊都比a[j]小,右邊都比a[j]大
// 如果j 為 high?如何處理?如果j為low,如何處理 ----> filter
int j =
partition
(a,low,high)
;// 將左邊再次分割槽
sort
(a,low,j-1)
;// 將右邊再次分割槽
sort
(a,j+
1,high);}
// 插入排序實現
private
static
void
insert
(comparable[
] a,
int low,
int high)
}}
private
static
intmedian3
(comparable[
] a,
int i,
int j,
int k)
public
static
void
sort
(comparable[
] a,
int low,
int high)
int m =
median3
(a,low,low +
(high - low +1)
/2,high)
;exchange
(a,low,m)
;// 分割槽,以j為分界點,左邊都比a[j]小,右邊都比a[j]大
// 如果j 為 high?如何處理?如果j為low,如何處理 ----> filter
int j =
partition
(a,low,high)
;// 將左邊再次分割槽
sort
(a,low,j-1)
;// 將右邊再次分割槽
sort
(a,j+
1,high)
;}
// 將整個陣列分為3個部分,
// lo-lt-1 是小於v的本分,
// lt-i-1 是等於v的部分,
// i-gt的部分不確定,保持移動,
// gt+1-hi的部分是大於v的部分
private
static
void
sort2
(comparable[
] a,
int lo,
int hi)
else
if(cmp >0)
else
}// a[lo..lt-1] < v = a[lt..gt] < a[gt+1..hi].
sort
(a, lo, lt-1)
;sort
(a, gt+
1, hi)
;}
更加完善的的切分方式,和針對重複值的優化
// does v == w ?
private
static
boolean
eq(comparable v, comparable w)
// 分為4個區域,新增變數 p,q,i,j lo-p等於v,p+1-i小於v,
private
static
void
sort3
(comparable[
] a,
int lo,
int hi)
// 中等數量計算一次中位數,三分取樣
else
if(n <=40)
// 大量資料,中位數中取中位數,再次三分取樣
else
// bentley-mcilroy 3-way partitioning
// 排序的時候: lo-p 位置等於v,p + 1 - i 位置//
int i = lo, j = hi+1;
int p = lo, q = hi+1;
comparable v = a[lo]
;while
(true
) i = j +1;
// 歸位
for(
int k = lo; k <= p; k++
)exchange
(a, k, j--);
for(
int k = hi; k >= q; k--
)exchange
(a, k, i++);
sort3
(a, lo, j)
;sort3
(a, i, hi)
;}
快速排序演算法筆記
個人理解 1 在一組資料中尋找基準數 2 在左右兩端開始比較,從右開始往左推遇到比基準數小的便停下定位,再從左開始往右推遇到比基準數大的數也停下定位,然後將這兩個數交換位置。4 最後將基準數放到資料中間,右邊留有比基準數大的數,左邊留有比基準數小的數。5 在以基準數為界,將兩邊再次分為兩組資料。6 ...
排序演算法筆記 快速排序 Quicksort
using system using system.collections.generic using system.linq using system.text namespace test sort array,0,array.length 1 console.readline 一次排序單元,完...
快速排序演算法 總結筆記
首先選擇乙個關鍵值key,作為樞軸。一般會將陣列的首個元素選定為key,樞軸。為什麼說是樞軸?是因為待會我們要以這個key為界,把所有小於等於key值的陣列元素放置到key的左側 把所有大於等於key值的元素移到陣列的右側。key,充當了乙個臨界軸的作用,所以叫它樞軸並不為過。定義兩個變數,firs...