之前看了選擇和插入排序,這兩個演算法是的時間複雜度均為o(n^2),而隨著問題規模n的增大,插入和選擇排序都比較慢。
歸併排序時的時間複雜度為o(nlgn) 其主要思想是分治法(divide and conquer),分就是要將n個元素的序列劃分為兩個序列,再將兩個序列劃分為4個序列,
直到每個序列只有乙個元素,最後,再將兩個有序序列歸併成乙個有序的序列。
例如兩個序列:
要歸併成乙個有序的序列,按照我們常規的方法,我們每次從兩個列表開頭元素選取較小的乙個,直到某乙個列表到達底部,再將另乙個剩下部分順序取出。其實如果將每個元素最後新增乙個最大值,則無需判斷是否達到列表盡頭。
**如下:merge函式的功能為將a中[low,mid],[mid+1,high]歸併成乙個有序的片段。
template void merge(t a,int low,int mid,int歸併排序就是多次呼叫mergehigh)
for (i=0;i1;i++)
//set the sentinel
left[llen-1] = numeric_limits::max();
right[rlen-1]= numeric_limits::max();
//merge the two array and copy to a[low,high];
int j = 0
;
int k = 0
;
for (i = low; i < high+1 ;i++)
else
}delete left;
delete right;
}
template這是乙個遞迴演算法,這個演算法的理解其實可以借助下面這個圖:merge_sort(t a,int low,int
high)
}
對於原始的陣列2,1,3,8,5,7,6,4,10,在整個過程執行的是順序是途中紅色編號1-20。雖然我們描述中說的是程式先分解,再歸併,但實際過程是一邊分解一邊歸併,前半部分分先排好序,後半部分再拍好,最後整個歸併為乙個完整的序列,途中的merge過程它所在層的兩個序列的merge過程:下圖展示了每個merge過程對作用於陣列的哪部分(紅色)。
整個過程就像乙個動態的樹,執行順序就是對樹的先序遍歷順序。
最後實驗驗證,對10000個倒序的陣列進行排序,直接插入排序需1024ms,二歸併排序只需20ms。
歸併排序詳解
一.概念 歸併是指將若干個已排序的子檔案合併成乙個有序的檔案。二.基本思路 設兩個有序的子檔案 相當於輸入堆 放在同一向量中相鄰的位置上 r low.m r m 1.high 先將它們合併到乙個區域性的暫存向量r1 相當於輸出堆 中,待合併完成後將r1複製回r low.high 中。合併過程中,設定...
歸併排序詳解
歸併排序的核心思想是將兩個已經排序的序列合併成乙個序列,那如何得到兩個已經排序的序列呢?我們知道,如果乙個序列只有乙個元素,那該序列是已經排序的,這樣我們就可以利用分治的思想,將未排序的序列劃分成更小的序列,只到我們可以很方便的對小序列進行排序 比如劃分到序列只有乙個元素,或者序列很小可以方便的使用...
歸併排序 詳解
歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法 divide and conquer 的乙個非常典型的應用,歸併排序將兩個已排序的表合併成乙個表。優點1.歸併排序的效率達到了巔峰 時間複雜度為o nlogn 這是基於比較的排序演算法所能達到的最高境界 2.歸併排序是一種穩定的...