排序演算法05 歸併排序

2021-07-31 08:45:32 字數 3122 閱讀 6822

歸併排序的演算法邏輯為把兩個有序的陣列歸併為乙個有序的陣列。

舉個例子,對於乙個長度為8的陣列,有兩種歸併方式

自頂向下的歸併:

1. 先分為[0-3],[4-7],左右有序後再歸併到一起就變成乙個完整的有序陣列了

2. 讓[0-3]有序又可以分為[0-1]、[2-3]有序,遞迴下去,最終歸併為[0-3]有序

自底向上的歸併:

先讓[0-1],[2-3],[4-5],[6-7]有序

再讓[0-3],[4-7]有序

最終歸併[0-7],讓整個陣列有序

* 原地歸併

* @param arr

* @param start

* @param mid

* @param end

*/function

merge

(arr,start,mid,end)

for(var n=start;n<=end;n++)else

if(j>end)else

if(temp[j]//右半邊的元素小於左半邊的元素(取右半邊的元素)

arr[n] = temp[j++];

}else}}

下面這張原地歸併軌跡的樣例圖來自於《演算法》第四版,左側為arr,右側為temp陣列

* 自頂向下的歸併

* 自底向上的歸併

* 原地歸併

* @param arr

* @param start

* @param mid

* @param end

*/function

merge

(arr,start,mid,end)

for(var n=start;n<=end;n++)else

if(j>end)else

if(temp[j]//右半邊的元素小於左半邊的元素(取右半邊的元素)

arr[n] = temp[j++];

}else

}}/**

* 自頂向下的歸併

* @param arr

* @param start

* @param end

*/function

sortdown

(arr,start,end)

/** * 自底向上的歸併

* @param arr

*/function

sortup

(arr)

}}//測試**

(function

() )();

package com.algs;

public

class

merge

for(int n=start;n<=end;n++)else

if(j>end)else

if(temp[j]//右半邊的元素小於左半邊的元素(取右半邊的元素)

arr[n] = temp[j++];

}else}}

private

static

void

sortdown(int arr,int temp,int start,int end)

private

static

void

sortup(int arr,int temp)}}

public

static

void

main(string args) ;

int temp1 = new

int[arr1.length];

sortdown(arr1,temp1,0,arr1.length-1);

for(int m:arr1)

system.out.println();

system.out.println("----------------");

int arr2 = ;

int temp2 = new

int[arr2.length];

sortup(arr2,temp2);

for(int n:arr2)}}

穩定。

非原地排序。

時間複雜度為nlogn

空間複雜度為n

歸併排序的主要缺點是輔助陣列所使用的額外空間和n的大小成正比

歸併排序的遞迴使小規模問題中方法的呼叫過於頻繁。使用插入排序處理小規模的子陣列(比如長度小於15)一般可以將歸併排序的執行時間縮短10%-15%

當陣列長度為2的冪時,自頂向下和自底向上的歸併排序所用的比較次數和陣列的訪問次數正好相同,只是順序不同。其它時候,兩種方法的比較和陣列的訪問次序會有所不同

github:

排序演算法 歸併排序

歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法 divide and conquer 的乙個非常典型的應用。首先考慮下如何將將二個有序數列合併。這個非常簡單,只要從比較二個數列的第乙個數,誰小就先取誰,取了後就在對應數列中刪除這個數。然後再進行比較,如果有數列為空,那直接將另...

排序演算法 歸併排序

include include define status int define max 20 typedef struct elemtype typedef struct sqlist void inital sqlist l 初始化 bool lt int i,int j void merge ...

排序演算法 歸併排序

歸併排序的思想其實完全是分治法的思想的體現,它完全遵循分治法的模式。這裡有必要再重提下分治法的思想 將原有的問題分解為幾個規模較小的但類似於原問題的子問題,遞迴的求解這些子問題,然後再合併這些子問題的解來求得原問題的解。現在來看看歸併排序的操作 1 將等待排序的含有 n 個元素的序列分解成各具有 n...