三路归并排序(附C++和Java代码)

三路归并排序(附C++和Java代码)

PS:阅读此文章需了解归并排序基本原理和二路归并排序

三路归并,即:将待排序数组等分为三个部分,然后一直分解到能直接求解为止(也就是分解到一个一个元素);最后自底向上逐一归并,直至最终合并为一个数组为止

对于大量数据,虽然三路归并比二路归并排序时间复杂度有所下降,但数量级仍为O(nlogn);空间复杂度也与二路归并一样O(n)

具体实现代码:

C++代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int a[maxn],b[maxn];
void Merge(int a[],int b[],int s,int mid,int midmid,int e){
    int i=s,j=mid+1,k=midmid+1;
    int t=i;
    while(i<=mid&&j<=midmid&&k<=e){
        if(a[i]<=a[j]&&a[i]<=a[k]){
            b[t++]=a[i++];
        }
        else if(a[j]<=a[k]&&a[j]<=a[i]){
            b[t++]=a[j++];
        }
        else{
            b[t++]=a[k++];
        }
    }
    while(i<=mid&&j<=midmid){
        if(a[i]<=a[j]){
            b[t++]=a[i++];
        }
        else{
            b[t++]=a[j++];
        }
    }
    while(j<=midmid&&k<=e){
        if(a[j]<=a[k]){
            b[t++]=a[j++];
        }
        else{
            b[t++]=a[k++];
        }
    }
    while(k<=e&&i<=mid){
        if(a[k]<=a[i]){
            b[t++]=a[k++];
        }
        else{
            b[t++]=a[i++];
        }
    }
    while(i<=mid){
        b[t++]=a[i++];
    }
    while(j<=midmid){
        b[t++]=a[j++];
    }
    while(k<=e){
        b[t++]=a[k++];
    }
}
void mergeSort(int a[],int s,int e){
    if(s<e){
        int mid=s+(e-s)/3;
        int midmid=e-(e-s)/3;
        mergeSort(a,s,mid);
        mergeSort(a,mid+1,midmid);
        mergeSort(a,midmid+1,e);
        Merge(a,b,s,mid,midmid,e);
        for(int i=s;i<=e;i++){
            a[i]=b[i];
        }
    }
}
int main(){
    int n;
    //表示待排序数组大小
    cin>>n;
    //输入待排序数组
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    mergeSort(a,1,n);

    //返回结果
    cout<<a[1];
    for(int i=2;i<=n;i++){
        cout<<" "<<a[i];
    }
    cout<<endl;
    return 0;
}

Java代码:
import java.util.*;

public class Main {
    public static int[] a=new int[100010];
    public static int[] b=new int[100010];
    public static void merge(int a[],int b[],int s,int mid,int midmid,int e){
        int i=s,j=mid+1,k=midmid+1;
        int t=s;
        while (i<=mid&&j<=midmid&&k<=e){
            if(a[i]<=a[j]&&a[i]<=a[k]){
                b[t++]=a[i++];
            }
            else if(a[j]<=a[k]&&a[j]<=a[i]){
                b[t++]=a[j++];
            }
            else{
                b[t++]=a[k++];
            }
        }
        while (i<=mid&&j<=midmid){
            if(a[i]<=a[j]){
                b[t++]=a[i++];
            }
            else{
                b[t++]=a[j++];
            }
        }
        while (j<=midmid&&k<=e){
            if(a[i]<=a[k]){
                b[t++]=a[i++];
            }
            else{
                b[t++]=a[k++];
            }
        }
        while (k<=e&&i<=mid){
            if(a[k]<=a[i]){
                b[t++]=a[k++];
            }
            else{
                b[t++]=a[i++];
            }
        }
        while (i<=mid){
            b[t++]=a[i++];
        }
        while (j<=midmid){
            b[t++]=a[j++];
        }
        while (k<=e){
            b[t++]=a[k++];
        }
    }
    public  static void mergeSort(int a[],int s,int e){
        if(s<e){
            int mid=s+(e-s)/3;
            int midmid=e-(e-s)/3;
            mergeSort(a,s,mid);
            mergeSort(a,mid+1,midmid);
            mergeSort(a,midmid+1,e);
            merge(a,b,s,mid,midmid,e);
            for(int i=s;i<=e;i++){
                a[i]=b[i];
            }
        }
    }
    public static void main(String args[]){
        Scanner scan=new Scanner(System.in);
        //输入待排序数组的大小
        int n=scan.nextInt();
        //输入待排序数组
        for(int i=1;i<=n;i++){
            a[i]=scan.nextInt();
        }
        mergeSort(a,1,n);

        //返回结果
        System.out.print(a[1]);
        for(int i=2;i<=n;i++){
            System.out.print(" "+a[i]);
        }
        System.out.println();
    }
}

  • 10
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值