自然归并

package Test1;

import java.util.Arrays;

public class Class1 {

    public static void main(String [] agrs){
        /**
        所有代码都需要再次改动,暂定此版本
         */
    int []a= new int[]{1, 5, 2, 3, 6, 0, 7, 4, 8,-1,9};
    int []temp=new int[a.length ];
//    System .out .println(a.length ) ;
    int []index= new int[a.length];
    int []NatureGroupingNumber=new int [1];
    int[] roundnumber = new int[1];
    GetPiont(a ,index ,NatureGroupingNumber ,a.length );
    /*
  System .out .println(Arrays .toString(a) );
   System .out .println(Arrays .toString(index)) ;
    System .out .println(NatureGroupingNumber[0]) ;
 */
    MergeSort(a,temp,index,NatureGroupingNumber,roundnumber);
    System .out .println(Arrays .toString(a) );

    }

    public static void Merge(int[] a, int[] temp,int l,int m, int r) {
        int i=l;
        int j=m+1;
        int k=l;
        while(i<=m&&j<=r){
            /**
             if(a[i++]<a[j++])
             原先写成了a[i++]跟a[j++],没注意看后面已经有a[i++],a[j++]导致数组溢出
             */
            if(a[i]<a[j])
                temp[k++]=a[i++];
            else
                temp[k++]=a[j++];
        }
        if(i>m)
            for(int q=j;q<=r;q++)
                temp[k++]=a[q];
         else
             for (int q = i; q <=m; q++)
                 temp[k++] =a[q];
    }

    public static void MergePass(int []a,int []index,int []roundernumber,int []NatureGroupingNumber,int []temp) {
        int i=0;
        /**
         while(i <= (NatureGroupingNumber[0] -roundernumber[0] *2))效果等同;
         当第一轮合并的时候,roundnumber=1;
         i=0
         i<8/(2*1)
         当第二轮合并的时候,roundnumber=1;
         它需要指向下一个的left,所以它变成了i=roundnumber*2+i=3;
     xxxxx    写while语句,当i<NatureGroupingNumber/(roundnumber*2),则可以继续循环下去,意思是左端点不大于中间
         的端点
                写while语句,只是控制循环的次数
                因为roundnumber是*2的增长的,所以为了表示右端点,所以i=i+roundnumber*2;
                不能将循环while写成:
         i<=(NatureGroupingNumber[0]/roundnumber/2)因为 i=i+roundnumber*2;
         i从0 开始,所以while条件里面 NatureGroupingNumber-roundernumber*2;剪掉一次合并
         */
        while(i <= (NatureGroupingNumber[0] -roundernumber[0] *2)){//AAAA
        int r=(i+2*roundernumber [0])<NatureGroupingNumber [0]?index [i+2*roundernumber[0] ]:a.length ;
        Merge(a,temp,index[i],index[i+roundernumber [0]]-1,r-1);
        // i=i+1;
        i=i+2*roundernumber [0];
        System.out .println("i:"+i) ;
        }/**
         原先一开始顺序错了
         比如说6组NatureGroupingNumber
         第一次是6组 两两都合并成功;所以最后i=NatureGroupingNumber=6;
         第二次只能合并前4组,所以i=4<NatureGroupingNumber=6,还剩2组不能合并,就只能暂时将它们后面两组赋值给已经合并好的组
         第三次合并,i=0,此时也不满足while语句的条件  所以i+roundnumber<NatureGroupingNumber,所以就让它们直接合并

        */
        /*if (i + roundernumber[0] >= NatureGroupingNumber[0]) {
            if(i<NatureGroupingNumber[0] ){
                for(int j=index [i];j<a.length ;j++)
                    temp[j]=a[j];

            }
        } else {
            Merge(a, temp, index[i], index[i + roundernumber[0] * 2], a.length - 1);
        }*/
        if(i<NatureGroupingNumber[0] )
        {
            for(int j=index [i];j<a.length ;j++)
                temp[j]=a[j];
        }
       if(i+roundernumber[0] <NatureGroupingNumber [0])
        {
            Merge(a,temp,index [i],index [i+roundernumber [0]]-1,a.length -1);
            System.out.println(11111);
        }
    }

    public static void MergeSort(int []a, int []temp, int[] index, int[] NatureGroupingNumber, int[] roundnumber) {
        roundnumber [0]=1;
        /**
        Exception in thread "main" java.lang.ArithmeticException: / by zero
        先前报有此错误,是因为没有赋值语句,导致分母为0
        所谓的分母指的是A处
         */
        while (roundnumber [0]<NatureGroupingNumber[0] ){
            /*
            第一次roundnumber=1;
            第二次roundnumber=2;
            roundnumber不是次数,是当前次数需要合并的组数;
             */
          //  System .out .println(roundnumber [0]/2+":"+roundnumber [0]) ;
            MergePass(a,index ,roundnumber ,NatureGroupingNumber ,temp) ;
            roundnumber[0]+=roundnumber[0];
          //   System .out .println(roundnumber [0]/2+":"+roundnumber [0]) ;
            MergePass(temp,index ,roundnumber ,NatureGroupingNumber,a) ;
            roundnumber[0]+=roundnumber[0];
        }

    }


    public static void GetPiont(int[] a, int []index,int []NatureGroupingNumber,int c){
        int j=0;
        index[j++]=0;
        for(int i=0;i<c-1;i++) {
            if(a[i]>a[i+1])
            {index[j++]=i+1;}
        }
        NatureGroupingNumber[0]=j;
        System .out .println(j) ;
    }

}

上面那个是对的,下面那个是理解有错误的…

package Test1;

import java.util.Arrays;

public class Class1 {

    public static void main(String [] agrs){
        /*
        所有代码都需要再次改动,暂定此版本
         */
    int []a= new int[]{1, 5, 2, 3, 6, 0, 7, 4, 8};
    int []temp=new int[a.length ];
//    System .out .println(a.length ) ;
    int []index= new int[a.length];
    int []NatureGroupingNumber=new int [1];
    int[] roundnumber = new int[1];
    GetPiont(a ,index ,NatureGroupingNumber ,a.length );
    /*
  System .out .println(Arrays .toString(a) );
   System .out .println(Arrays .toString(index)) ;
    System .out .println(NatureGroupingNumber[0]) ;
 */
    MergeSort(a,temp,index,NatureGroupingNumber,roundnumber);
    System .out .println(Arrays .toString(a) );

    }

    public static void Merge(int[] a, int[] temp,int l,int m, int r) {
        int i=l;
        int j=m+1;
        int k=l;
        while(i<=m&&j<=r){
            /**
             if(a[i++]<a[j++])
             原先写成了a[i++]跟a[j++],没注意看后面已经有a[i++],a[j++]导致数组溢出
             */
            if(a[i]<a[j])
                temp[k++]=a[i++];
            else
                temp[k++]=a[j++];
        }
        if(i>m)
            for(int q=j;q<=r;q++)
                temp[k++]=a[q];
         else
             for (int q = i; q <=m; q++)
                 temp[k++] =a[q];
    }

    public static void MergePass(int []a,int []index,int []roundernumber,int []NatureGroupingNumber,int []temp) {
        int i=0;
        /**
         while(i <= (NatureGroupingNumber[0] -roundernumber[0] *2))效果等同;
         当第一轮合并的时候,roundnumber=1;
         i=0
         i<8/(2*1)
         当第二轮合并的时候,roundnumber=1;
         它需要指向下一个的left,所以它变成了i=roundnumber*2+i=3;
         写while语句,当i<NatureGroupingNumber/(roundnumber*2),则可以继续循环下去,意思是左端点不大于中间
         的端点
         */
        while(i <= (NatureGroupingNumber[0] /(roundernumber[0] * 2))){//AAAA
        int r=(i+2*roundernumber [0])<NatureGroupingNumber [0]?index [i+2*roundernumber[0] ]:a.length ;
        Merge(a,temp,index[i],index[i+roundernumber [0]]-1,r-1);
        // i=i+1;
        i=i+2*roundernumber [0];
        }
        if (i + roundernumber[0] >= NatureGroupingNumber[0]) {
            if(i<NatureGroupingNumber[0] ){
                for(int j=index [i];j<a.length ;j++)
                    temp[j]=a[j];

            }
        } else {
            Merge(a, temp, index[i], index[i + roundernumber[0] * 2], a.length - 1);
        }
    }

    public static void MergeSort(int []a, int []temp, int[] index, int[] NatureGroupingNumber, int[] roundnumber) {
        roundnumber [0]=1;
        /*
        Exception in thread "main" java.lang.ArithmeticException: / by zero
        先前报有此错误,是因为没有赋值语句,导致分母为0
        所谓的分母指的是A处
         */
        while (roundnumber [0]<NatureGroupingNumber[0] ){
            /*
            第一次roundnumber=1;
            第二次roundnumber=2;
            roundnumber不是次数,是当前次数需要合并的组数;
             */
            System .out .println(roundnumber [0]) ;
            MergePass(a,index ,roundnumber ,NatureGroupingNumber ,temp) ;
            roundnumber[0]+=roundnumber[0];
            System .out .println(roundnumber [0]) ;
            MergePass(temp,index ,roundnumber ,NatureGroupingNumber,a) ;
            roundnumber[0]+=roundnumber[0];
        }

    }


    public static void GetPiont(int[] a, int []index,int []NatureGroupingNumber,int c){
        int j=0;
        index[j++]=0;
        for(int i=0;i<c-1;i++) {
            if(a[i]>a[i+1])
            {index[j++]=i+1;}
        }
        NatureGroupingNumber[0]=j;
        System .out .println(j) ;
    }

}

代码需要修改,很多地方加了我对程序的理解,我自己觉得可以100%明白;
主要是我刚学java还不太懂调用方法,因为我只知道它是拷贝传值。。。
然鹅,传了一个值过去他又没法改变;
然后我又知道数组是地址存的,所以我所有的数据都是数组…
这是我照着原来大佬写的代码

---------------------------------------------END-------------------------------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值