演算法4 2 3快速排序筆記

2021-10-11 03:28:18 字數 4675 閱讀 4101

熵最佳排序

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...