0
点赞
收藏
分享

微信扫一扫

算法之归并排序

快乐小码农 2022-02-11 阅读 110

一、什么是归并排序?
1.概念

归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法,归并排序对序列的元素进行逐层折半分组,然后从最小分组开始比较排序,合并成一个大的分组,逐层进行,最终所有的元素都是有序的

2.算法原理

基本思想

归并排序就是递归得将原始数组递归对半分隔,直到不能再分(只剩下一个元素)后,开始从最小的数组向上归并排序。

将一个数组拆分为两个,从中间点拆开,通过递归操作来实现一层一层拆分。
从左右数组中选择小的元素放入到临时空间,并移动下标到下一位置。
重复步骤2直到某一下标达到尾部。
将另一序列剩下的所有元素依次放入临时空间。
将临时空间的数据依次放入原数据数组
概念图

分解的时候我们可以使用递归的方式进行

首先我们可以先定义三个变量,

数组的头部位置可以定义为 low,数组的尾部可以定义为high

因为每次分解都是要折半,所以我们可以定义数组的中间是 mid,如下图所示

 

我们从上图当中可以看到,我们每一次递归,都是将原来的mid当成新的high,一直到low = high的时候我们就已经可以说明我们将一个数据分离了出来。所以我们可以写以下代码来表示分。

public static void mergeSort(int[] a, int low, int high) {
        //首先判断 low 和 high是否指向一个地方
        if(low >= high) {
            return;
        }
        int mid = (low + high)/2;
        //先递归左边
        mergeSort(a, low, mid);
        //在递归右边
        mergeSort(a, mid+1, high);
 
    }


首先我们可以先递归左边,直到我们讲第一个值分离出去,然后再回溯,分离他右边的那个,如下如所以:

当递归完成之后我们该开始合并了

 public static void mergeSort(int[] a, int low, int high) {
        //首先判断 low 和 high是否指向一个地方
           // 正常情况下就是 == 
        if(low == high) {
            return;
        }
        int mid = (low + high)/2;
        //先递归左边
        mergeSort(a, low, mid);
        //在递归右边
        mergeSort(a, mid+1, high);
        //合并
        merge(a,low,mid,high);
        System.out.println(Arrays.toString(a));
    }

首先我们需要先弄懂一个地方就是合并是在哪里开始的。

首先我们要知道我们第一次回溯之后,将第二个元素分离了出来,第二个元素分离完成之后,也会回溯回去,那么此一次合并就是 值 6 和 5的合并。

下边我们为了演示选择了 5,6 , 1 , 3的合并过程

 首先我们需要弄清楚,我们这里所谓的分离其实是概念意义上的,在我们的数组结构上其实并没有分离,而且由于回溯的原因 5,6 , 1 , 3是其实和上边是对应的关系,如图所示

下边我们来一步一步的展示整个合并的过程,

首先我么可以定义两个指针,s1和s2,然后在定义一个新的临时数组来存储数据

 我们将指针s1的范围锁定在 s1<=min ,将指针s2的范围锁定在s2<=high,我们可以比较s1和s2当前指向的值的大小,将小的一方放入到临时数组当中去,直到s1或s2一方指向为空,那么就可以将另一方全部放入到临时数组当中去。然后将临时的代码在放回数组
代码如下:

 

 代码如下:

package com.sen;
 
import java.util.Arrays;
 
public class Gui {
 
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int arr[] = {6,5,3,1,8,7,2,4};
        mergeSort(arr,0,arr.length-1);
        System.out.println("排序结果:"+Arrays.toString(arr));
 
    }
    public static void mergeSort(int[] a, int low, int high) {
        //首先判断 low 和 high是否指向一个地方
           // 正常情况下就是 == 
        if(low == high) {
            return;
        }
        int mid = (low + high)/2;
        //先递归左边
        mergeSort(a, low, mid);
        //在递归右边
        mergeSort(a, mid+1, high);
        //合并
        merge(a,low,mid,high);
        System.out.println(Arrays.toString(a));
    }
    //合并
    public static void merge(int[] a,int low,int mid,int high) {
        //定义第一段
        int s1 = low;
        //定义第二段
        int s2 = mid+1;
        //定义临时数组
        int[] temp =new int[high-low+1];
        int i = 0;
        
        //判断s1,s2是否有数据,放入临时数组
        while(s1<=mid) {
            temp[i++]=a[s1++];
        }
        while(s2<=high) {
            temp[i++]=a[s2++];
        }
        for(int j = 0;j < temp.length;j++) {
            a[j+low]=temp[j];
        }
    }
    
 
}
 

举报

相关推荐

0 条评论