首页 > 代码库 > 三分归并排序

三分归并排序

一直以来做题目用的都是sort函数,突然要自己写归并算法确实挺头痛的。

尤其是一开始连归并排序是什么都搞不懂,最后看了半天书终于明白二分归并,那么三分的也就呼之欲出了

  1 #include <iostream>  2 #include <cstdio>  3 #include <cstring>  4 using namespace std;  5   6 #define N 100005  7 int a[N],b[N],c[N];  8   9 //这个函数不断用来找三段区域中的最小值的那个点,以便用来将找到的点存入b数组中 10 int minn(int i,int j,int l) 11 { 12     if(a[i]<a[j]&&a[i]<a[l]) 13         return 1; 14     else if(a[j]<a[i]&&a[j]<a[l]) 15         return 2; 16     else 17         return 3; 18 } 19 //每次合并三个区域后,一个区域率先完成,那接下来两个区域继续合并就用下面这个函数 20 void mergeTwoArray(int st1,int la1 , int st2, int la2 ,int k,int *a,int *b) 21 { 22     int i = st1,j=st2; 23     while(i<=la1&&j<=la2){ 24         if(a[i]<a[j]) 25             b[k++] = a[i++]; 26  27         else 28             b[k++] = a[j++]; 29     } 30     if(i<=la1) 31         while(i<=la1) 32             b[k++] = a[i++]; 33     if(j<=la2) 34         while(j<=la2) 35             b[k++] = a[j++]; 36 } 37 //合并三段区域的过程 38 void mov(int x,int m,int n,int y,int *a,int *b) 39 { 40     int i=x,j=m+1,l=n+1,k=x; 41     while(i<=m&&j<=n&&l<=y){ 42         int t = minn(i,j,l); 43         if(t == 1) 44             b[k++] = a[i++]; 45  46         else if(t == 2) 47             b[k++] = a[j++]; 48  49         else 50             b[k++] = a[l++]; 51     } 52  53     if(i>m) 54         mergeTwoArray(j,n,l,y,k,a,b);//说明左侧区域元素用尽,带入参数继续合并其他两个区域,后面else if中的语句也是同一个意思 55     else if(j>n) 56         mergeTwoArray(i,m,l,y,k,a,b); 57     else 58         mergeTwoArray(i,m,j,n,k,a,b); 59 } 60  61 void cpy(int x,int y,int *a,int *b) 62 { 63     for(int i=x;i<=y;i++) 64         a[i] = b[i]; 65 } 66  67 //总的归并过程 68 void mergeSort(int x,int y,int *a) 69 { 70     if(x>=y) 71         return; 72     int thi1 = (y-x)/3+x; 73     int thi2 = y-(y-x)/3; 74     mergeSort(x,thi1,a);//合并最左边 75     mergeSort(thi1+1,thi2,a);//合并中间区域 76     mergeSort(thi2+1,y,a);//合并右侧区域 77  78     //将分割的三块区域不断找到最小值后从a数组移入b数组 79     mov(x,thi1,thi2,y,a,b); 80     //将b数组的元素重新移回a数组 81     cpy(x,y,a,b); 82 } 83  84 int main() 85 { 86     int T; 87     printf("输入测试样例数: "); 88     scanf("%d",&T); 89     while(T--){ 90         int n; 91         printf("输入元素的个数: "); 92         scanf("%d",&n); 93         printf("依次输入所有的元素:"); 94         for(int i=0;i<n;i++){ 95             scanf("%d",a+i); 96         } 97         mergeSort(0,n-1,a); 98         printf("输出三分排序后的结果:\n"); 99         for(int i=0;i<n;i++){100             printf("%d ",a[i]);101         }102         puts("");103     }104     return 0;105 }

 

三分归并排序