Java 排序演算法2

2021-07-13 23:23:47 字數 4115 閱讀 4402

相關部落格–排序演算法1:

插入排序演算法描述:記錄存放在陣列r[0….n-1]中,排序過程的某一中間時刻,r被劃分成兩個子區間r[0…i-1]和r[i….n-1],其中:前乙個子區間是已排好序的有序區;後乙個子區間則是當前未排序的部分。

基本操作:將當前無序區的第1個記錄r[i]插入到有序區r[0….i-1]中適當的位置,使r[0…i]變為新的有序區。

操作細節:當插入第i(i≥1)個物件時, 前面的r[0], r[1], …, r[i-1]已經排好序。

用r[i]的關鍵字與r[i-1], r[i-2], …的關鍵字順序進行比較(和順序查詢類似),如果小於,則將r[x]向後移動(插入位置後的記錄向後順移);找到插入位置即將r[i]插入。

直接插入排序:關鍵字比較次數和記錄移動次數與記錄關鍵字的初始排列有關。

最好情況下, 排序前記錄已按關鍵字從小到大有序, 每趟只需與前面有序記錄序列的最後乙個記錄比較1次, 移動2次記錄, 總的關鍵字比較次數為 n-1, 記錄移動次數為 2(n-1)。在平均情況下的關鍵字比較次數和記錄移動次數約為n² /4。

直接插入排序是一種穩定的排序方法

直接插入排序最大的優點是簡單,在記錄數較少時,是比較好的辦法。

二分插入排序: 在直接插入排序的基礎上,利用二分(折半)查詢演算法決策出當前元素所要插入的位置。

二分查詢:找到中間元素,如果中間元素比當前元素大,則當前元素要插入到中間元素的左側;否則,中間元素比當前元素小,則當前元素要插入到中間元素的右側。

找到當前元素的插入位置i之後,把i和high之間的元素從後往前依次後移乙個位置,然後再把當前元素放入位置i。

希爾排序演算法描述:先取定乙個小於n的整數gap1作為第乙個增量,把整個序列分成gap1組。所有距離為gap1的倍數的元素放在同一組中,在各組內分別進行排序(分組內採用直接插入排序或其它基本方式的排序)。然後取第二個增量gap2

public

class sortmethods

插入排序

// insertsort1(a);

插入+二分

// binaryinsertsort2(a);

//4希爾排序

// shellsort(a);

//5快速排序

// quiksort(a,0,a.length-1);

//6歸併排序

mergesort(a,0,a.length-1);

print(a);

}//6歸併排序:將兩個或兩個以上的有序表組合成乙個新的有序表。

private

static

void

mergesort(int a, int i, int j)

}private

static

void

copyarray(int a, int b, int left, int right)

}private

static

void

merge(int a, int b, int left, int mid, int right)

}if(p>mid)

}else}}

/*快速排序:

* 以某個記錄為界(該記錄稱為支點或樞軸),將待排序列分成兩部分:

* ①一部分: 所有記錄的關鍵字大於等於支點記錄的關鍵字

* ②另一部分: 所有記錄的關鍵字小於支點記錄的關鍵字

*/private

static

void

quiksort(int a,int left,int right)

}private

static

intpatition(int a, int left, int right)

swap(a,j,i);

}swap(a,left,j);

return j;

}//4希爾排序又稱縮小增量排序,是2023年由d.l.shell提出來的。

private

static

void

shellsort(int a) }}

if(gap>1)else}}

private

static

void

binaryinsertsort2(int a) else

}// for(int j=i+1;j>high+1;j--)

for(int j=i;j>high;j--)

a[high+1]=temp;// a[low]=temp;}}

public

static

void

insertsort1(int a)

}a[j+1]=temp;}}

private

static

void

swap(int a, int i, int j)

private

static

void

print(int a)

}}

快速排序演算法描述:任取待排序記錄序列中的某個記錄(例如取第乙個記錄)作為基準(樞),按照該記錄的關鍵字大小,將整個記錄序列劃分為左右兩個子串行,左側子串行中所有記錄的關鍵字都小於或等於基準記錄的關鍵字 ,右側子串行中所有記錄的關鍵字都大於基準記錄的關鍵字,基準記錄則排在這兩個子串行中間(這也是該記錄最終應安放的位置)。然後分別對這兩個子串行重複施行上述方法,直到所有的記錄都排在相應位置上為止。

基準記錄也稱為樞軸(或支點)記錄。取序列第乙個記錄為樞軸記錄,其關鍵字為pivotkey。指標low指向序列第乙個記錄位置,指標high指向序列最後乙個記錄位置。

注:游標high用於搜尋比樞軸小的記錄,游標low用於搜尋比樞軸大的記錄,搜尋就和樞軸交換並切換游標。

演算法分析:快速排序是乙個遞迴過程,快速排序的趟數取決於遞迴樹的高度。如果每次劃分對乙個記錄定位後, 該記錄的左側子串行與右側子串行的長度相同, 則下一步將是對兩個長度減半的子串行進行排序, 這是最理想的情況。

演算法評價:時間複雜度:

最好情況(每次總是選到中間值作樞軸)t(n)=o(nlogn)

最壞情況(每次總是選到最小或最大元素作樞軸)t(n)=o(n²)

空間複雜度:

最壞情況:s(n)=o(n)

一般情況:s(n)=o(logn)

快排的優化:可以證明,快速排序演算法在平均情況下的時間複雜性和最好情況下一樣,也是o(nlogn),這在基於比較的演算法類中算是快速的,快速排序也因此而得名。

快速排序演算法的效能取決於劃分的對稱性。因此通過修改partition( )方法,可以設計出採用隨機選擇策略的快速排序演算法,從而使期望劃分更對稱,更低概率出現最壞情況。

因此,可在原劃分方法中加入如下**進行優化:

public

static

intpartition(int a, int p, int r)

歸併排序(2-路歸併排序):設初始序列含有n個記錄,則可看成n個有序的子串行,每個子串行長度為1。

兩兩合併,得到 n/2 個長度為2或1的有序子串行。

再兩兩合併,……如此重複,直至得到乙個長度為n的有序序列為止。

演算法分析:合併排序法主要是將兩筆已排序的資料合併和進行排序。如果所讀入的資料尚未排序,可以先利用其它的排序方式來處理這兩筆資料,然後再將排序好的這兩筆資料合併。

演算法評價:

時間複雜度:t(n)=o(nlogn)

空間複雜度:s(n)=o(n)

氣泡排序 ,選擇排序 ,插入排序 :平均與最快的時間複雜度都是o(n²)。初學排序必須知道的三個基本排序方式,雖然速度不快而不實用,但排序的方式值得理解與學習的。

希爾排序 :雖然也是o(n²),但分組後的n值更小。利用前一次排序後的結果,以加快排序的速度。可用shell排序法改良三個基本排序方式。

快速排序:目前所公認最快的排序方法之一(o(nlogn) ,視解題物件而定),雖然在最差狀況下可以達o(n²),但在多數的情況下,效率表現是相當不錯的。

歸併排序 :時間複雜度與快排方式相近,但需借助輔助空間。 它更適合於對儲存在不同陳列或不同檔案中的資料進行排序。

Java演算法 2 插入排序

1.定義 1 插入排序類似於咱們日常打撲克的時候,通常我們給牌排序時,總是將一張牌插入到其他已經有序的排中的適當位置。2 由 1 可知,插入排序是通過遍歷陣列,並將當前元素與前面已經排好序的元素一一比較,獲得最佳位置 3 為了給要插入的元素騰出空間,需要將其餘所有元素在插入之前都向後移動一位。4 與...

java排序演算法

1.定義 通過比較來確定輸入序列1,a 2,a n 的元素間相對次序的排序演算法稱為比較排序演算法。2.演算法解釋 1 選擇排序 選擇排序的基本思想是對待排序的記錄序列進行n 1遍的處理,第i遍處理是將l i.n 中最小者與l i 交換位置。這樣,經過i遍處理之後,前i個記錄的位置已經是正確的了。2...

Java排序演算法

回顧一下排序演算法 稍微地設計一下基礎類 插入排序 插入排序 insertion sort 的基本思想是 每次將乙個待排序的記錄,按其關鍵字大小插入到前面已經排好序的子檔案中的適當位置,直到全部記錄插入完成為止。氣泡排序 氣泡排序 bubblesort 的基本概念是 依次比較相鄰的兩個數,將小數放在...