栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

交换排序-归并排序

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

交换排序-归并排序

返回目录

目录
  • 基本思想
  • 自己的理解
  • 动画演示
  • 归并排序示例
  • 代码解析

基本思想

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子
序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序
表,称为二路归并。——黑马程序员

自己的理解

将一个数组分为两个已经排序好的数组,然后按照顺序一一进行大小对比,然后将两个数组合并到一个数组中。。。(胡言乱语了)

动画演示


排序的活动就如同示例图所示这般。
每次都将数组分为左右两部分,先将左部分的数据排好顺序后再排右部分数据的顺序,两部分都拍好之后进行归并。
第一次分为左右部分数据时,左部分右是一个新的数组,右部分也是一个新的数组,再分别进行分左右部分的操作(所以需要使用递归)。
直到左右数组中都只有一个数据时递归结束(此时左右的数据都只有一个,那么一定是有序的)
因为有序,所以可以进行归并操作。
此时左边的数据已被归并完毕,然后再进行右边数据的归并操作,最后再进行左右的数据的归并操作,依次反复直到整个数组有序。

归并排序示例
package com.stu.algorithm.copy;

import java.util.Arrays;


public class Merge {
    public static int[] temp;
    public static void main(String[] args) {
        int a[] = {8,4,5,7,1,3,6,2};
        sort(a);
        System.out.println(Arrays.toString(a));
    }
    public static void sort(int[] a){
        //数组最左边的元素的下标
        int l = 0;
        //数组最右边的元素的下标
        int r = a.length - 1;
        //为临时存储的数组空间赋值
        temp = new int[a.length];
        sort(l,r,a);
    }

    public static void sort(int l, int r, int a[]){
        if (l>=r){//当左下标大于等于右下标时直接返回
            return ;
        }
        int mid = l + (r - l)/2;
        //对l到mid之间的元素进行排序
        sort(l,mid,a);
        //对mid到r之间的元素进行排序
        sort(mid+1,r,a);
        //进行两两归并
        merge(l,mid,r,a);
    }

    public static void merge(int l, int mid, int r, int a[]){
        //指向临时数组的下标
        int i = l;
        //指向左半边数组的下标
        int p1 = l;
        //指向右半边数组的下标
        int p2 =mid + 1;
        //当两边的数组都还没归并结束时持续循环
        while (p1 <= mid && p2 <= r){
            if (a[p1] < a[p2]){
                temp[i++] = a[p1++];
            }else {
                temp[i++] = a[p2++];
            }
        }
        //假设p1指向的这部分数组中的数据没有全部归并,将数组中的数据都填入临时的数组中
        while (p1<=mid){
            temp[i++] = a[p1++];
        }
        while (p2<=r){
            temp[i++] = a[p2++];
        }
        //将在临时数组中已经有序的数组写入正式的数组中
        for (int j = l; j <= r; j++) {
            a[j] = temp[j];
        }
    }

}

代码解析




还需要这两个循环是因为在归并时,总会有一半数组中的所有元素首先进入临时的数组中,另一个数组中还有值没有进入数组中,但我我们并不清除是哪个数组中的数据没有完全写入临时数组中,所以要写两个判断,但是这两个循环只会执行一个循环。

自己常出现的错误,在循环时总会忘记最后一个值(也就是循环条件是要等于最高位元素的下标)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/298336.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号