原地歸併排序相比於普通歸併排序,不需要開拓額外空間就可進行兩個有序陣列的merge,故空間複雜度為o(1)
無論是原地歸併排序還是普通歸排序 最外層的遞迴形式都是統一的,如下
void mergesort(int *arr,int low,int high)
}
下面首先給出普通的merge 函式,需要申請輔助陣列,現將待合併的兩個陣列都拷進去。
#define max_len 20
int b[max_len];
void merge(int *arr,int low,int
mid,int high)
while(i<=mid) arr[k++]=b[i++];
while(j<=high) arr[k++]=b[j++];
}
下面給出原地歸併排序中merge函式的原理介紹
i 往後移動,找到第乙個arr[i]>arr[j]的索引。如圖找到30
j往後一棟,找到第乙個arr[j]>arr[i]的索引。如圖找到55
交換i到index-1和index到j的部分,採用區域性陣列迴圈移動的方法,通過三次陣列逆序實現。交換後陣列前半部分區域性有序,之後重複進行此步驟即可實現兩個有序陣列的合併。
**如下:
void reverse(int *arr,int n) //逆序操作
void merge(int *arr,int begin,int mid,int end)
exchange(arr+i,j-i,j-i-step);
i+=step;}}
附上完整的測試**
#include
#include
#define max_len 20
int b[max_len];
void reverse(int *arr,int n) //逆序操作
}void exchange(int *arr,int n,int i) //將含有n個元素的陣列迴圈左移i個位置
//void merge(int *arr,int begin,int mid,int end)
////
// exchange(arr+i,j-i,j-i-step);
// i+=step;
// }
//}//
void merge(int *arr,int low,int mid,int high)
while(i<=mid) arr[k++]=b[i++];
while(j<=high) arr[k++]=b[j++];
}void mergesort(int *arr,int low,int high)
}int main(int argc, char
const *argv)
; int testbrr = ;
int len=sizeof(arr)/sizeof(arr[0]);
mergesort(arr,0,len-1);
for (int i=0;iprintf("%d ",arr[i]);
return
0;}
原地歸併排序
原地歸併排序 原地歸併排序不需要輔助陣列既可以歸併。關鍵在於merge函式。假設有兩段遞增的子陣列arr begin.mid 1 和arr mid.end 但是整個陣列不是遞增的。其中i begin,j mid,k end 第一步 i往後移動,找到第乙個arr i arr j 的索引,假設陣列元素如...
自頂向下的原地歸併排序
歸併排序是一種簡單的遞迴排序演算法。思路 歸併排序即是將兩個有序的陣列歸併成乙個更大的有序陣列。那麼我們要將乙個陣列排序,我們可以先將這個陣列分成兩半分別排序,然後將結果歸併起來。其 歸併排序的速度非常快,但是卻需要額外的空間。為什麼需要額外的空間尼?因為我們使用歸併排序時是將兩個不同的有序陣列歸併...
Java版 原地二路歸併排序
思想 先將原始陣列劃分為n個較小的子陣列,然後對每個子陣列兩兩進行排序並合併為乙個次子陣列 重複上述過程直到次子陣列的個數為1即為排序後的原始陣列 時間複雜度 o n logn 最好 壞情況 空間複雜度 o n 為了解決原始二路歸併排序空間複雜度較高的情況而產生的,思想很巧妙,很是佩服。它在將原始的...