二分归并排序算法
1. 問題
對于n個不同的數(shù)構成的數(shù)組A[1…n]進行排序,其中n = 2k。
2. 解析
二分歸并排序算法原理(假設數(shù)組A中共有n個元素):
將數(shù)組A中n個元素看成n個獨立的子序列,因此每個子序列的長度為1,然后兩兩合并,得到[n/2]個長度為2或1(注意如果n為奇數(shù)時,就會出現(xiàn)多出一個元素無法與其他元素合并)的有序子序列;再兩兩合并,一種重復下去,直到得到一個長度為n的有序數(shù)組為止。
二分歸并排序算法實現(xiàn)步驟(分而治之):
1、將待排序數(shù)組從中間一分為二,對左右兩邊在進行遞歸分割操作,得到若干個相互獨立的子數(shù)組;
2、再對(1)中獲得的若干個獨立的子序列遞歸的執(zhí)行合并操作,最終得到有序的數(shù)組;
3、合并操作的實現(xiàn)(以升序為例):
①假設已經有兩個有序數(shù)列,分別存放在兩個數(shù)組s,r中;并設i,j分別為指向數(shù)組的第一個單元的下標;s有a個元素,r有b個元素;
②再另設一個數(shù)組temp,k指向該數(shù)組的第一個單元下標;
③比較數(shù)組s第i個元素和數(shù)組r第j個元素,將小的元素放入數(shù)組temp,元素的原先下標與k均往后移動一位;
④重復步驟③,直至i=a或j=b為止。
二分歸并排序算法實現(xiàn)過程(假設n=8):
1、初始化數(shù)組A
2、將數(shù)組A從中間一分為二
3、對步驟2中所得的兩個數(shù)組分別從中間一分為二
4、對步驟3中所得的四個數(shù)組分別從中間一分為二
5、按照升序,兩兩合并步驟4中獲得的八個數(shù)組
6、按照升序,兩兩合并步驟5中獲得的四個數(shù)組
7、按照升序,合并步驟6中獲得的兩個數(shù)組
注,:以步驟7為例,分析如何將兩個有序的子序列合并成一個有序序列:
3. 設計
二分歸并排序算法的偽代碼:
void Merge_Sort(int A[], int left, int right){int mid, k, i, j;int temp[Max]; //暫時存儲的數(shù)組mid = (left + right) / 2; //標記數(shù)組一分為二時的界線k = left; //標記數(shù)組temp的下標i = left; //標記前半部分數(shù)組的下標 j = mid + 1; //標記后半部分數(shù)組的下標if(left == right) return; //當完成數(shù)組的拆分時,返回Merge_Sort(left, mid); //對前半部分數(shù)組進行歸并排序Merge_Sort(mid + 1, right); //對后半部分數(shù)組進行歸并排序while(兩部分數(shù)組都未遍歷完){if(前半部分數(shù)組中下標為i的元素 > 后半部分數(shù)組中下標為j的元素)將下標為j的元素存入數(shù)組temp中;k與j均往后移動一位;else將下標為i的元素存入數(shù)組temp中;k與i均往后移動一位;}while(若前半部分數(shù)組中的全部元素已存在于數(shù)組temp中,后半部分數(shù)組還未完全遍歷完){將后半部分數(shù)組還未遍歷的元素依次存入數(shù)組temp中;}while(若后半部分數(shù)組中的全部元素已存在于數(shù)組temp中,前半部分數(shù)組還未完全遍歷完){將前半部分數(shù)組還未遍歷的元素依次存入數(shù)組temp中;}for(i 到 n){將數(shù)組temp中的值依次復制給數(shù)組A;} }4. 分析
將一個規(guī)模為n的問題分成兩個規(guī)模均為n/2的子問題,時間為2T(n/2),又因為合并的時間復雜度為O(n),總時間為T(n) = 2T(n / 2) + O(n)。故,二分歸并排序算法的時間復雜度為O(nlog2n),且最壞、最佳、平均情況下二分歸并排序時間復雜度均為O(nlog2n)。
因為借助了規(guī)模為n的temp數(shù)組進行排序,故,二分歸并排序算法的空間復雜度為O(n)。
5. 源碼
二分歸并排序算法的源碼地址:
https://github.com/Ying917/Algorithm-Analysis/blob/master/Merge_Sort.cpp
總結
- 上一篇: 需求工程week1
- 下一篇: go run 和 go build 和