C++歸并排序代碼實現(xiàn)示例代碼
1 算法核心思想
歸并排序是一種高效的排序方式,需要用到遞歸來實現(xiàn),我們先來看一下動圖演示:
算法核心思想如下:
1.將數(shù)組盡量平均分成兩段。
2.將這兩段都變得有序(使用遞歸實現(xiàn))。
3.將兩段合并。
2 代碼實現(xiàn)
首先,我們先定義一個歸并排序的函數(shù),里面接受三個參數(shù):
void MergeSort(int arr[], int left, int right) { }
arr代表需要進(jìn)行排序的數(shù)組,left表示數(shù)組arr的最左端點,right表示數(shù)組arr的最右端點。
首先我們需要把數(shù)組分成兩段,我們可以用二分的方法:
int mid = (left + right) >> 1;
這里右移(>>為右移運算符)1為和除以2含義相同。
也可以用防溢出,因為left+right的值可能會爆int,導(dǎo)致結(jié)果錯誤:
int mid = left + (right - left) >> 1;
然后對兩段分別進(jìn)行遞歸,第一段是[1, mid],第二段是[mid+1, right]:
MergeSort(arr, left, mid); MergeSort(arr, mid + 1, right);
由于我們需要對數(shù)組進(jìn)行操作,但是直接在arr操作可能會導(dǎo)致原始數(shù)據(jù)丟失,但是如果再創(chuàng)建一個數(shù)組會占用內(nèi)存,所以我們可以向電腦“租借”right-left+1個空間,用關(guān)鍵字new來完成:
int* tmp = new int[right - left + 1];
注意要以指針的形式定義。
由于我們要把數(shù)組變得有序,而我們歸并排序的思想就是分而治之,然后再依次變得有序,需要用到分治的思想。那么我們先定義一些變量:
int cur = 0, cur1 = left, cur2 = mid + 1;
cur為tmp數(shù)組的元素下標(biāo),cur1為第一段的最左端點,cur2為第二段的最左端點。
然后我們對tmp數(shù)組和arr數(shù)組進(jìn)行循環(huán)操作,這里可以用while循環(huán),循環(huán)條件是cur1<=mid&&cur2<=right。
如果arr[cur1]比arr[cur2]更大,那么就先把a(bǔ)rr[cur2]放回tmp,否則放arr[cur1]。
代碼:
while(cur1 <= mid && cur2 <= right) { if(arr[cur1] < arr[cur2]) tmp[cur++] = arr[cur1++]; else tmp[cur++] = arr[cur2++]; }
然后處理可能有的數(shù)組殘余未處理的部分:
while(cur1 <= mid) tmp[cur++] = arr[cur1++]; while(cur2 <= right) tmp[cur++] = arr[cur2++];
然后合并數(shù)組,方法跟處理時差不多的:
for(int i = 0; i < right - left + 1; i++) arr[left + i] = tmp[i];
就是把tmp的元素依次賦值給arr。
最有我們需要把tmp的空間還給內(nèi)存,所以我們delete一下:
delete[] tmp;
然后我們的arr就變的有序了。
但是,如果這樣寫,程序就成功被我們干崩了,因為我們忘記寫遞歸出口了,補(bǔ)一個遞歸出口:
if(left == right) return;
我們合并一下整段代碼:
void MergeSort(int arr[], int left, int right) { if(left == right) return; int mid = (left + right) >> 1; MergeSort(arr, left, mid); MergeSort(arr, mid + 1, right); int* tmp = new int[right - left + 1]; int cur = 0, cur1 = left, cur2 = mid + 1; while(cur1 <= mid && cur2 <= right) { if(arr[cur1] < arr[cur2]) tmp[cur++] = arr[cur1++]; else tmp[cur++] = arr[cur2++]; } while(cur1 <= mid) tmp[cur++] = arr[cur1++]; while(cur2 <= right) tmp[cur++] = arr[cur2++]; for(int i = 0; i < right - left + 1; i++) arr[left + i] = tmp[i]; delete[] tmp; }
3 算法時間復(fù)雜度
正常情況下,歸并排序時間復(fù)雜度為:
O(NLogN)
到此這篇關(guān)于C++歸并排序代碼實現(xiàn)的文章就介紹到這了,更多相關(guān)C++歸并排序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Qt圖形圖像開發(fā)曲線圖表模塊QChart庫縮放/平移詳細(xì)方法與實例
這篇文章主要介紹了Qt圖形圖像開發(fā)曲線圖表模塊QChart庫縮放/平移詳細(xì)方法與實例,需要的朋友可以參考下2020-03-03Eclipse中C++連接mysql數(shù)據(jù)庫
這篇文章主要為大家詳細(xì)介紹了Eclipse中C++連接mysql數(shù)據(jù)庫 ,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-06-06