【排序演算法】歸併排序
小編記得在老早以前就梳理過一期排序演算法,可是小編從未精講,這一次就單獨拿出眾所周知的歸併排序來講一講吧。
【問題引入】
在生活中,我們常常會看到一些數字,需要你來排序,當數字數量較大時,我們就會用到計算機來處理,那麼如果是你,你會怎麼寫這個程式呢?
【題目分析】
如果你有一定的基礎,一定會想到使用排序演算法,你會用什麼呢?冒泡?插入?歸併?快排?
今天我們來精講歸併排序。
【歸併排序】
1)使用思想:分治;
2)演算法圖解:
3)程式碼如下:
1 #include<iostream> 2 using namespace std; 3 int data[1000],result[1000]; 4 void merge_compare(int l,int r) 5 { 6int mid=(l+r)>>1; 7int left_start=l; 8int left_end=mid; 9int right_start=mid+1; 10int right_end=r; 11int result_start=l; 12while(left_start<=left_end&&right_start<=right_end)//將兩個子序列合併 13{ 14if(data[left_start]<data[right_start]) 15result[result_start++]=data[left_start++]; 16else 17result[result_start++]=data[right_start++]; 18} 19while(left_start<=left_end)//將左序列剩餘放入陣列中 20result[result_start++]=data[left_start++]; 21while(right_start<=right_end)//將右序列剩餘放入陣列中 22result[result_start++]=data[right_start++]; 23 } 24 void merge_sort(int l,int r) 25 { 26if(l==r) return;//只有一個數時返回 27if(r-l==1) 28{ 29if(data[l]>data[r]) 30swap(data[l],data[r]); 31return;//兩個數時直接交換順序 32} 33int mid=(l+r)>>1; 34merge_sort(l,mid);//劃分左序列 35merge_sort(mid+1,r);//劃分右序列 36merge_compare(l,r);//劃分完成後合併 37for(int i=l;i<=r;i++) 38data[i]=result[i];//將臨時陣列中的值賦給原陣列 39 } 40 int main() 41 { 42int n; 43cin>>n; 44for(int i=1;i<=n;i++) 45cin>>data[i]; 46merge_sort(1,n); 47for(int i=1;i<=n;i++) 48cout<<data[i]<<" "; 49return 0; 50 }
親測能用:
4)優劣成都:
優:穩定,速度快
劣:空間複雜度較高
5)與快速排序的差別
個人認為歸併排序很穩定,速度已經很快了,只不過空間複雜度較高。而快速排序極不穩定,時快時慢,最慢能成為氣泡排序一樣,而歸併卻保持在O( n log n)的速度,所以平時最好用歸併。
之前曾寫過各路傳奇排序,講的種類較多,有興趣的讀者可以看一看。