数据结构---归并排序

第一步:分组

第1层分成2个大组,每组n/2个元素;
第2层分成4个小组,每组n/4个元素;
第3层分成8个更小的组,每组n/8个元素;
一直到每组只有一个元素。
在这里插入图片描述

第二步:归并

当每个小组内部比较出先后顺序以后,小组之间会展开进一步的比较和排序,合并成一个大组;大组之间继续比较和排序,再合并成更大的组…最终,所有元素合并成了一个有序的集合。
在这里插入图片描述

归并操作

把两个有序的小集合,归并成一个有序的大集合
这正是归并排序的核心所在,需要三个步骤

第一步

创建一个额外的大集合,用于存储归并结果,长度是两个小集合之和。

在这里插入图片描述

p1,p2,p是三个辅助指针,用于记录当前操作的位置

第二步

从左到右逐一比较两个小集合中的元素,把较小的元素优先放入大集合。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

第三步

从另一个还有剩余元素的集合中,把剩余元素按顺序复制到大集合尾部。
在这里插入图片描述

JAVA实现

先划分,然后排序

    public static void myMergeSort(int[] array,int start,int end){
        //把数组拆分为俩个,分别递归,直到划分为1个单位(start<end来判断)。
        System.out.println("现在的起点是: "+start+"终点是: "+end);
        if(start<end){
            int mid = (start+end)/2;
            myMergeSort(array,start,mid);
            myMergeSort(array,mid+1,end);
            merge(array,start,mid,end);
        }
    }

具体排序的代码:

    private static void merge(int[]array,int start,int mid,int end){
        System.out.println("开始排序");
        int[] tempArray = new int[end-start+1];
        int p1 = start;//左边数组的头指针
        int p2 = mid+1;//右边数组的头指针
        int p0 = 0;//大数组的头指针
        //比较小数组的值,依次放入
        while ((p1<=mid)&&(p2<=end)){
            if(array[p1]<=array[p2]){
                tempArray[p0++]=array[p1++];
            }else {
                tempArray[p0++]=array[p2++];
            }
        }
        //到这里有一侧的数组放完了,但可能还有一侧数组没放完
        //左侧数组没完
        while (p1<=mid){
            tempArray[p0++] = array[p1++];
        }
        //右侧数组没完
        while (p2<=end){
            tempArray[p0++] = array[p2++];
        }
        //在把大集合赋值回去原来的数组
        //array[i+start]=  tempArray[i];的原因是: 原来是start是从数组中随机截取的。。。
        //i+start中的start相当于偏移量。。。
        for (int i =0;i<tempArray.length;i++){
            array[i+start]=  tempArray[i];
        }
    }

测试方法:

    public static void main(String[] args) {
        int [] array = new int[]{5,8,6,3,9,2,1,7};
        myMergeSort(array,0,array.length-1);
        System.out.println(Arrays.toString(array));
    }

在这里插入图片描述
这个打印结果可以清楚的看出调用栈的顺序。注意体会。。。。

总结

时间复杂度:O(nlogn)
每一层的运算量:n x 层级数:logn.
空间复杂度:O(n)
单次归并操作开辟的最大空间是n
归并排序是稳定排序

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值