归并排序的递归及非递归实现

归并排序总的思想:将待排序数组划分为一小段,一小段的”小数组“,刚开始“小数组”长度为1 ,比较时,都是这些“小数组”之间进行比较,第一次比较完成之后,“小数组”长度*2,个数相应减少,在进行比较,每次比较完后,单个的“小数组”都是有序的了,直到“小数组”长度等于待排序数组,此时,整个待排序数组就有序了。归并排序完成

package DS;

import java.util.Arrays;
import java.util.Random;

class MyMergeSort{
    //归并
    private void merge(int[] array, int start,int mid, int end,int[] tmpArray) {
     //   int[] tmpArray = new int[array.length];
        int tmpIndex = start;
        int i = start;
        int s2 = mid+1;
        //有俩个归并段
        while(start<=mid && s2<=end){
            //俩个归并段都从头开始比较
            // 小的拉到创建好的数组里
            //再将索引++;直到有一个归并段没数据,跳出循环
            if (array[start] <= array[s2]){
                tmpArray[tmpIndex++] = array[start++];
            }else{
                tmpArray[tmpIndex++] = array[s2++];
            }
        }
        //说明第一个归并段有数据
        while (start <= mid){
            tmpArray[tmpIndex++] = array[start++];
        }
        //第二个归并段有数据
        while (s2 <= end){
            tmpArray[tmpIndex++] = array[s2++];
        }
        //把排好序的数据从tmpArray拷贝array
        while (i<=end){
            array[i] = tmpArray[i];
            i++;
        }
    }

//递归
    void mergeSort(int[] array, int start, int end,int[] tmpArray){
        if(start>=end){
            return;
        }
        int mid = (start+end)/2;
        mergeSort(array,start,mid,tmpArray);
        mergeSort(array,mid+1,end,tmpArray);
        merge(array,start,mid,end,tmpArray);
    }
    //非递归
    //归并
    public void merge2(int[] array,int gap){
        int[] tempArray = new int[array.length];
        int i = 0;//tempArray下标
        int start1 = 0;
        int end1 = start1+gap-1;
        int start2 = end1+1;
        int end2 = start2+gap-1<=array.length-1?start2+gap-1:array.length-1;
        //保证有俩个归并段
        while (start2 < array.length) {
            //保证俩个归并段都有数据
            while(start1<=end1 && start2<=end2){
                //比较
                if(array[start1]<array[start2]){
                   tempArray[i++] = array[start1++];
                }else{
                    tempArray[i++] = array[start2++];
                }
            }
            //退出循环是因为start2<=end2不成立,及说明start1~end1里还有未比较的数据
            while (start1 <= end1){
                tempArray[i++] = array[start1++];
            }
            //退出循环是因为start1<=end1不成立,及说明start2~end2里还有未比较的数据
            while (start2<=end2){
                tempArray[i++] = array[start2++];
            }
            //至此,及说明一次二路归并已走完,以下为修改指针,准备下一段归并
            start1 = end2 + 1;
            end1 = start1 + gap - 1;
            start2 = end1 + 1;
            end2 = start2+gap-1<=array.length-1?start2+gap-1:array.length-1;
        }
        //当start2,end2,甚至end1已经越界时,start1还有数据,且未处理,要把他作为未归并的
        //数据,拉到tempArray里
        while(start1 <array.length){
            tempArray[i++] = array[start1++];
        }
        //拷贝数据到原始数组
        //此处只能用for遍历去拷贝
        for(int j = 0;j<tempArray.length;j++){
            array[j] = tempArray[j];
        }
    }
    void mergeSort2(int[] array){
        for(int i = 1;i<array.length;i *= 2){
            merge2(array,i);
        }
    }
}

public class MergeSort {
    public static void main(String[] args) {
        MyMergeSort myMergeSort = new MyMergeSort();
        int[] array = new int[10000];
        Random random = new Random();
        for(int i = 0;i<array.length;i++){
            array[i] = random.nextInt(100000)+1;
        }
        int[] tmpArray = new int[array.length];
        //myMergeSort.mergeSort(array,0,array.length-1,tmpArray);
        myMergeSort.mergeSort2(array);
        System.out.println(Arrays.toString(array));
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值