歸併排序——將兩個有序表直接歸併為一個有序表
阿新 • • 發佈:2019-01-10
歸併排序是多次將兩個或兩個以上的有序表合併成一個新的有序表。最簡單的歸併是直接將兩個有序的子表合併成一個有序的表,即二路歸併
二路歸併的排序基本思想是:
將a[0……n-1]看成是n個長度為1的有序序列,然後進行兩兩歸併,得到n/2(向上取整)個長度為2(最後一個有序序列的長度可能為1)的有序序列,再進行兩兩歸併,得到n/4(向上取整)個長度為4(最後一個有序序列的長度可能小於4)的有序序列……直到得到一個長度為n的有序序列
歸併排序每趟產生的有序區只是區域性有序的,也就是說在最後一趟排序結束前,所有元素並不一定歸位了
每次從兩個段中取出一個元素進行關鍵字的比較,將較小者放入c[ ]中,最後將各段餘下的部分直接複製到c[ ]中
#include<stdio.h> #include<iostream> using namespace std; //a[]、b[]為需要合併的兩個陣列,c為合併後的新陣列,n為a[]的長度,m為b[]的長度 void merge(int a[],int b[],int c[],int n,int m){ int i=0,j=0,k=0;//i為a[]的下標,j為b[]的下標,k為c[]的下標 //在a[]和b[]均未掃描完時迴圈 while(i<n && j<m){ if(a[i]<=b[j]) c[k++]=a[i++]; else c[k++]=b[j++]; } //如果a[]還有剩餘,則將餘下部分賦值過去 while(i<n){ c[k++]=a[i++]; } //如果b[]還有剩餘,則將餘下部分賦值過去 while(j<m){ c[k++]=b[j++]; } } int main(){ int n,m;//n為a[]的長度,m為b[]的長度 //初始化 //陣列a[] cout<<"n:"; cin>>n; int *a=new int[n]; cout<<"輸入"<<n<<"個數的第一個有序列表:"; for(int i=0;i<n;i++){ cin>>a[i]; } //陣列b[] cout<<"m:"; cin>>m; int *b=new int(m); cout<<"輸入"<<m<<"個數的第二個有序列表:"; for(int i=0;i<m;i++){ cin>>b[i]; } int *c=new int(n+m);//c為合併後的陣列 //歸併兩個有序列表 merge(a,b,c,n,m); //輸出 cout<<"合併後為:"; for(int i=0;i<n+m;i++){ cout<<c[i]<<" "; } cout<<endl; }