【归并排序】基础代码

🍋前言

最近在学习分治法,涉及到之前学习的归并排序,当时学习数据结构的时候就归并排序背后的内容没有深究,过去留下的问题,在现在的使用中展现出不足,写下一些学习中的总结和思考,认真探讨归并排序。

🤔算法思想

归并排序是是分治法思想的典型代表,根据分治法的思想可以分为以下过程

1.划分:将待排序序列划分1n划分成为两个长度相等的子序列1n/2和n/2+1到n

2.求解子问题:分别对这两个子序列进行排序,的到两个有序的子序列

3.合并:将这两个有序子序列合并成一个有序序列

⭐️如何代码实现

首先要将原始的序列划分成为两个子序列,对于划分后的左右序列也要采用同样的策略进行划分,因此可以采用递归的方式去调用,当划分到的序列只有一个记录的时候,算是递归出口(因为一个记录本身就是有序的),划分的结果是将n个记录的待排序序列划分成n个长度为1的有序子序列;接下来需要进行合并操作,合并的时候由于是在原数组上进行排序操作,需要一个辅助数组来暂存当前排序好的元素,合并是对当前的两个子序列进行合并,基本思路和数据结构中的合并两个有序数组一样,通过由1个记录之间的合并到整个左序列和整个右序列之间的合并,最后得到的就是排序好的序列。

💻代码

package LOQ.排序;

import java.util.Arrays;
import java.util.Scanner;

/*
归并排序 
 */
public class MergeSort {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("Please input array length:");
        int len = sc.nextInt();
        System.out.println("please input array element:");
        int[] arr = new int[len];
        for(int i=0;i<len;i++) {
            arr[i]=sc.nextInt();
        }
        mergeSort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }
    //拆分数组,成为单个有序的
    private static void mergeSort(int[] arr,int low,int high) {
        //当low==high的时候,只有一个元素,所以不需要排序
        if(low<high) {
            //得到中间值,把原来的数组分成两部分
            int mid = (low+high)/2;
            //递归调用左半部分进行分组
            mergeSort(arr,low,mid);
            //递归调用右半部分进行分组
            mergeSort(arr,mid+1,high);
            //合并左半部分和右半部分
            merge(arr,mid,low,high);
        }
    }
    //合并左半部分和右半部分
    private static void merge(int[] arr,int mid,int low,int high) {
        //记录左区域的第一个值
        int lPot = low;
        //记录右区域的第一个值
        int hPot = mid+1;
        //临时数组的起始值,也就是low
        int start = 0;
        //合并的临时数组
        int[] temp = new int[high-low+1];
        //合并两个有序序列
        while(lPot<=mid && hPot<=high) {
            //左区域第一个元素小于右区域第一个元素
            if(arr[lPot]<arr[hPot]) {
                temp[start++] = arr[lPot++];
            } else {
                temp[start++] = arr[hPot++];
            }
        }
        //合并左区域剩余元素
        while(lPot<=mid) {
            temp[start++] = arr[lPot++];
        }
        //合并右半区域元素
        while(hPot<=high) {
            temp[start++] = arr[hPot++];
        }
        //覆盖原数组空间
        for(int i=0;i<temp.length;i++) {
            arr[i+low] = temp[i];
        }
    }
}

🙈结尾

这里列举的只是2路归并排序,算法描述的还不够清晰,还有代码优化也没有实现,等有时间再补充其他内容。

2022年3月11日15:44:11

posted @ 2022-03-11 19:21  Lnnau  阅读(30)  评论(0)    收藏  举报  来源