归并排序的递归算法和非递归算法
之前在排序算法里面都说过归并排序的递归算法了,现在算法课正在学,所以就在补充一下,有关归并排序的递归算法和非递归算法。
归并排序的时间复杂度是nlogn,且最坏最好都是一样的,但是不在位(即需要额外的存储空间)。自己挂个之前的排序链接过来点击打开链接
下面是归并的递归算法代码(偷懒不再打一遍了。。)
#include <iostream>
#include <cstdio>
using namespace std;
int x[1000];
int y[1000];
void Merge(int low, int mid, int high)
{
int i, j, k;
int t;
i = low;
j = mid+1;
for(k=low; i<=mid&&j<=high; k++)
{
if(x[i] <= x[j])
y[k] = x[i++];
else
y[k] = x[j++];
}
while(i <= mid)
{
y[k++] = x[i++];
}
while(j <= high)
{
y[k++] = x[j++];
}
for (t=low; t<=high; t++)
{
x[t] = y[t];
}
}
void MSort(int low, int high) /* 定义归并排序函数,递归方式 */
{
int mid;
if(low < high)
{
mid = (low+high)/2;
MSort(low, mid); /* 递归调用,将子序列x[low~mid]归并为有序序列 */
MSort(mid+1, high); /* 递归调用,将子序列x[mid+1~high]归并为有序序列 */
Merge(low,mid,high); /* 将子序列x[low~mid]和x[mid+1~high]进行归并 */
}
}
void Print(int n)
{
for(int i=1; i<=n; i++)
printf("%d ", x[i]);
printf("\n");
}
int main()
{
int n;
scanf("%d", &n);
for(int i=1; i<=n; i++)
{
scanf("%d", &x[i]);
}
MSort(1, n);
Print(n);
return 0;
}
然后是今天的主要的非递归的算法,大概说一下思路咯。对于一个数组,采用递归是因为可以将一个数组的排序划分成两个小数组的排序,然后每个小数组又可以化成两个小数组直到最后变成一个数字然后在将结果合并在一起。然后转变一下思路,我们从底部开始思考,首先取一个数字让该数字与和它相邻的数字进行排序,然后在取两个数字组成小数组,让该小数组与和它相邻的长度为二的小数组进行排序.......直到最后长度为n。这样写下来就是非递归的归并排序啦~
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
const int MAX = 10000;
int a[MAX], n;
int b[MAX];
void Merge(int a[], int b[], int l, int m, int r){//把a数组合并到b数组
int i = l, j = m+1, k = l;
while((i<=m) && (j<=r)){
if(a[i] <= a[j])
b[k++] = a[i++];
else
b[k++] = a[j++];
}
if(i > m){
for(int q = j; q<=r; q++){
b[k++] = a[q];
}
}
else{
for(int q = i; q<=m; q++){
b[k++] = a[q];
}
}
return;
}
void MergeSort(int a[], int n){
int s = 1;
while(s<n){
int i=0;
while(i <= n-2*s){
//合并到数组b
Merge(a, b, i, i+s-1, i+2*s-1);
i = i+2*s;
}
if(i+s<n){
Merge(a, b, i, i+s-1, n-1);
}
else{
for(int j=i; j<=n-1; j++)
b[j] = a[j];
}
s += s;
i=0;
while(i <= n-2*s){
//合并到数组a
Merge(b, a, i, i+s-1, i+2*s-1);
i = i+2*s;
}
if(i+s<n){
Merge(b, a, i, i+s-1, n-1);
}
else{
for(int j=i; j<=n-1; j++)
a[j] = b[j];
}
s += s;
}
}
int main(){
scanf("%d", &n);
for(int i=0; i<n; i++){
scanf("%d", &a[i]);
}
MergeSort(a, n);
for(int i=0; i<n; i++){
printf("%d ", a[i]);
}
return 0;
}