在對數組進行合併排序時,每每會用到遞歸。而一趕上遞歸,就很容易被迷住。畢竟,遞歸的過程細節是很燒腦的。這時,若是再來幾個子函數,就更嗨了。下面就說一說我本身碰見的這個遞歸:數組
template<class T>函數
void MergeSort(T a[],int left,int right){
int t=right-left;
t++;
T b[t];//每次遞歸,定義一個與處理數據數量相等大小的數組,暫存處理後的數組
if(left<right){
int i=(left+right)/2;
MergeSort(a,left,i);//這兩次不一樣形式的遞歸結果爲
MergeSort(a,i+1,right);//將數組一分爲二後兩側順序排好
Merge(a,b,left,i,right);//將排完順序的半成品數組徹底排好:即合併到數組b
Copy(a,b,left,right);//將排好序的數組從新放回數組a
}
}spa
下面咱們就具體說一說Merege和Copy這兩個子函數的具體細節:blog
template<class T>排序
void Merge(T a[],T b[],int left,int mid,int right){//將當前範圍(left-right)中的數據按必定次序存入b數組
int i=left,j=mid+1;
int t=0;
while(i<=mid&&j<=right){
if(a[i]>a[j]){
b[t++]=a[j++];
}else{
b[t++]=a[i++];
}
}
while(i<=mid){
b[t++]=a[i++];
}
while(j<=right){
b[t++]=a[j++];
}遞歸
}索引
template<class T>class
void Copy(T a[],T b[],int left,int right){//將最後排好順序的元素從新放回aim
int t=0;//此處應注意的是咱們處理的數據是a數組中的,而合併排序時將每次排好順序的數據放回a中,此時要特別注意放回的方式,要將數據放回原來的索引範圍,數據
for(int i=left;i<=right;i++){//而不是單純的放回去,下面給出一張圖幫助理解
a[i]=b[t++];
}
}
template<class T>
void Copy(T a[],T b[],int left,int right){//這是將複製簡單理解爲複製回a後的錯誤函數 int t=right-left+1; for(int i=0;i<t;i++){ a[i]=b[i];//這樣的後果就是改變a數組原有內容,形成意想不到的計算結果 } }