【算法基础】-- 归并排序篇 - 归并排序

归并排序与那些基于交换、选择等排序的思想不一样,“归并”的含义是将两个或两个以上的有序表组合成一个新的有序表。

思想是:
假定待排序表含有 n 个记录,则可将其视为 n 个有序的子表,每个子表的长度为 1 ,然后两两归并,得到 ⌈ n / 2 ⌉ (向上取整)个长度为 2 或 1 的有序表:再两两归并…如此重复,直到合并成一个长度为 n 的有序表为止。
如图
在这里插入图片描述
辅助数组问题:对于归并排序的辅助数组,这里的代码是 O ( n ),即整个算法就一个辅助数组,设置一个长度为n的辅助数组,并为全局变量每次迭代都可使用

k路归并:对于 N 个元素进行 k 路归并排序时,排序的趟数 m 满足,k^m = N,从而 m = logk(N),又考虑到 m 为整数,所以 m = ⌈ logk(N) ⌉

时间复杂度问题:每趟排序时间复杂度为 O ( n ),共需要进行 O ( logn )趟,故总的时间复杂度为 O ( nlogn ) 。

算法实现

/*
    2路归并排序:
        时间复杂度->最好情况:O(nlogn)、平均情况:O(nlogn)、最坏情况:O(nlogn)
        空间复杂度->O(n)
        是否稳定->是
*/
#include<bits/stdc++.h>
using namespace std;
typedef int ElemType;
#define n 6
ElemType *B=(ElemType *)malloc((n+1)*sizeof(ElemType));//申请辅助空间
void Merge(ElemType A[],int low,int mid,int high){
    int i,j,k;
    for(int k=low;k<=high;k++){//将A[]中的元素复制到辅助数组中去
        B[k]=A[k];
    }
    for(i=low,j=mid+1,k=i;i<=mid&&j<=high;k++){//将B[]中较大的先复制到A[]中
        if(B[i]<=B[j]){//此处的小于等于号决定了归并排序是一个稳定的排序
            A[k]=B[i++];
        }
        else{
            A[k]=B[j++];
        }
    }
    while(i<=mid) A[k++]=B[i++];//将剩余的全部复制到A[]中国
    while(j<=high) A[k++]=B[j++];
}

void MergeSort(ElemType A[],int low,int high){
    if(low<high){
        int mid=(low+high)/2;
        MergeSort(A,low,mid);
        MergeSort(A,mid+1,high);
        Merge(A,low,mid,high);
    }
}

int main(){
    ElemType A[n]={5,4,2,3,1,0};
    MergeSort(A,0,n-1);
    for(int i=0;i<n;i++){
        cout<<A[i]<<" ";
    }
    return 0;
}

发布了83 篇原创文章 · 获赞 15 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_42127861/article/details/103127729