归并排序

归并排序MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治divide-and-conquer策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。

一、归并排序的思想


【1】如下图,可以看到这种结构很像一棵完全二叉树,本文的归并排序我们采用递归去实现(也可采用迭代的方式去实现)。分阶段可以理解为就是递归拆分子序列的过程。
归并排序_第1张图片
【2】归并排序思想示意图2(合并相邻有序子序列):再来看看治阶段,我们需要将两个已经有序的子序列合并成一个有序序列,比如上图中的最后一次合并,要将[4,5,7,8]和[1,2,3,6]两个已经有序的子序列,合并为最终序列[1,2,3,4,5,6,7,8],来看下实现步骤:会使用到一个临时内存变量temp;
归并排序_第2张图片归并排序_第3张图片

二、归并排序案例


归并排序的应用案例:给你一个数组,val arr = Array(5,4,6,3,7,2,8,9,1,0,8,3), 请使用归并排序完成排序。

package com.algorithms;

import java.util.Arrays;

/**
 * 归并排序
 */
public class MergeSort {
    public static void main(String[] args) {
        int arr[] = new int[]{5,4,6,3,7,2,8,9,1,0,8,3};
        MergeSort mergeSort = new MergeSort();
        mergeSort.mergeSort(arr,0,arr.length-1,new int[arr.length]);
        System.out.printf(Arrays.toString(arr));
    }

    //分解数据 + 合并数据
    public void mergeSort(int arr[],int left,int right,int[] temp){
        if(left < right){
            int mid = (left + right)/2;
            //传入左区间
            mergeSort(arr,left,mid,temp);
            //传入右区间
            mergeSort(arr,mid+1,right,temp);
            //合并
            merge(arr,left,mid,right,temp);
        }
    }

    /*
     * 合并方法思想:【1】、将left——mid 之间的数据 与 mid+1——right 之间的数据进行比较,并顺序的放到 temp 中;
     * 【2】上述结束后,情况一:右边的数据遍历结束,但是左边的数据还有时,将左边的全部数据复制到temp中;
     *                 情况二:左边的数据遍历结束,但是右边的数据还有时,将右边的全部数据复制到temp中;
     */
    public void merge(int[] arr,int left,int mid,int right,int[] temp){
        //temp的下标
        int t = 0;
        //left 的值后续要用这里暂存起来
        int l = left;
        //因为右边的元素对mid进行了操作,所以这里需要获取传入的mid并锁死
        int m = mid;
        while(left <= m && mid+1 <= right){
            if(arr[left] < arr[mid+1]){
                temp[t] = arr[left];
                t++;
                left++;
            }else{
                temp[t] = arr[mid+1];
                t++;
                mid++;
            }
        }
        //情况一
        while(left <= m){
            temp[t] = arr[left];
            t++;
            left++;
        }
        //情况二
        while(mid+1 <= right){
            temp[t] = arr[mid+1];
            mid++;
            t++;
        }
        //将temp的值复制到arr中
        //先将temp的下标还原
        t=0;
        while(l <= right){
            arr[l] = temp[t];
            t++;
            l++;
        }
    }
}


----关注公众号,获取更多内容----

你可能感兴趣的:(数据结构和算法)