跟着AI学算法-排序算法-归并排序,剖析排序过程

跟着AI学算法-排序算法-归并排序,剖析排序过程归并排序是一种分治算法,它将待排序数组分成两个子数组,分别对子数组进行排序,然后将两个已排序的子数组合并成一个有序的数组。这个过程不断地递归执行

欢迎大家来到IT世界,在知识的湖畔探索吧!

归并排序是一种分治算法,它将待排序数组分成两个子数组,分别对子数组进行排序,然后将两个已排序的子数组合并成一个有序的数组。这个过程不断地递归执行,直到子数组长度为1,即可视为已经排好序的。

直白点将就是对数组一直拆分成左右两个数组,直到子数组长度为1,然后左右两边元素合并排序,并返回递归上层继续排序,直至数组排序完成。

具体步骤如下:

  1. 将待排序的数组分成两个子数组,可以使用数组下标来实现。
  2. 对每个子数组进行递归拆分,直到子数组长度为1。
  3. 将两个已排序的子数组合并成一个有序的数组。合并过程中,创建一个临时数组,依次比较两个子数组的首个元素,将较小的元素放入临时数组中,直到其中一个子数组为空。然后将剩余的另一个子数组中的元素全部复制到临时数组的末尾。
  4. 返回合并后的有序数组。
跟着AI学算法-排序算法-归并排序,剖析排序过程

执行过程请移步文章末尾:排序执行过程。

归并排序的时间复杂度为O(nlogn),空间复杂度为O(n),是一种稳定的排序算法。

AI编码实现:

跟着AI学算法-排序算法-归并排序,剖析排序过程

本地测试:

为了能够打印排序过程,代码稍作修改。

package com.algorithm.sort;

import java.util.Arrays;

/**
 * @author LuoFei
 * @className: MergeSort
 * @projectName algorithm
 * @description: TODO
 * @date 2023/2/21 15:45
 */
public class MergeSort{

    public static void mergeSort(int[] arr, int left, int right, int deep) {
        deep ++;
        System.out.print("递归深度:"+deep +"; left="+left+", right="+right);
        if (left < right) {
            int mid = (left + right) / 2;
            System.out.println(", mid="+mid+"; 排序左侧数组;");
            // 对左侧子数组进行排序
            mergeSort(arr, left, mid, deep);
            // 对右侧子数组进行排序
            System.out.println("递归深度:"+deep +"; 排序右侧数组; ");
            mergeSort(arr, mid + 1, right, deep);
            // 合并两个已排序的子数组
            System.out.println("递归深度:"+deep +"; 开始合并数组; ");
            System.out.println("---------------------------------------");
            merge(arr, left, mid, right);
            System.out.println("---------------------------------------");
            System.out.print("递归深度:"+deep +"; 合并后数组; "+Arrays.toString(arr) );
        }
        System.out.println();
        System.out.println("****************递归返回*****************");
    }

    public static void merge(int[] arr, int left, int mid, int right) {
        int[] temp = new int[right - left +1];
        System.out.println("比较前临时数组:"+Arrays.toString(temp));
        int i = left, j = mid + 1, k = 0;
        //比较左右两个子数组的元素,将较小的元素放入临时数组中
        while (i <= mid && j <= right) {
            System.out.println("比较["+i+", "+j+"]号位数字["+arr[i]+", "+arr[j]+"]");
            if (arr[i] < arr[j]) {
                temp[k++] = arr[i++];
            } else {
                temp[k++] = arr[j++];
            }
        }
        System.out.println("比较后临时数组:"+Arrays.toString(temp));
        //将左侧子数组中剩余的元素复制到临时数组中
        System.out.print("复制左侧剩余元素:");
        while (i <= mid) {
            System.out.print(arr[i]);
            temp[k++] = arr[i++];
        }
        System.out.println();
        System.out.println("复制左侧剩余元素后,临时数组:"+Arrays.toString(temp));
        //将右侧子数组中剩余的元素复制到临时数组中
        System.out.print("复制右侧剩余元素:");
        while (j <= right) {
            System.out.print(arr[j]);
            temp[k++] = arr[j++];
        }
        System.out.println();
        System.out.println("复制右侧剩余元素后,临时数组:"+Arrays.toString(temp));
        //将临时数组中的元素复制回原数组
        for (i = left, k = 0; i <= right; i++, k++) {
            arr[i] = temp[k];
        }
    }

    public static void main(String[] args) {
        int[] arr = {5, 2, 8, 3, 9, 1};
        System.out.println("初始数组:"+Arrays.toString(arr));
        System.out.println("=======================================");
        mergeSort(arr, 0, arr.length - 1, 0);
        System.out.println("=======================================");
        System.out.println("最终数组"+Arrays.toString(arr));
    }
}

欢迎大家来到IT世界,在知识的湖畔探索吧!

排序执行过程:

欢迎大家来到IT世界,在知识的湖畔探索吧!初始数组:[5, 2, 8, 3, 9, 1]
=======================================
递归深度:1; left=0, right=5, mid=2; 排序左侧数组;
递归深度:2; left=0, right=2, mid=1; 排序左侧数组;
递归深度:3; left=0, right=1, mid=0; 排序左侧数组;
递归深度:4; left=0, right=0
****************递归返回*****************
递归深度:3; 排序右侧数组; 
递归深度:4; left=1, right=1
****************递归返回*****************
递归深度:3; 开始合并数组; 
---------------------------------------
比较前临时数组:[0, 0]
比较[0, 1]号位数字[5, 2]
比较后临时数组:[2, 0]
复制左侧剩余元素:5
复制左侧剩余元素后,临时数组:[2, 5]
复制右侧剩余元素:
复制右侧剩余元素后,临时数组:[2, 5]
---------------------------------------
递归深度:3; 合并后数组; [2, 5, 8, 3, 9, 1]
****************递归返回*****************
递归深度:2; 排序右侧数组; 
递归深度:3; left=2, right=2
****************递归返回*****************
递归深度:2; 开始合并数组; 
---------------------------------------
比较前临时数组:[0, 0, 0]
比较[0, 2]号位数字[2, 8]
比较[1, 2]号位数字[5, 8]
比较后临时数组:[2, 5, 0]
复制左侧剩余元素:
复制左侧剩余元素后,临时数组:[2, 5, 0]
复制右侧剩余元素:8
复制右侧剩余元素后,临时数组:[2, 5, 8]
---------------------------------------
递归深度:2; 合并后数组; [2, 5, 8, 3, 9, 1]
****************递归返回*****************
递归深度:1; 排序右侧数组; 
递归深度:2; left=3, right=5, mid=4; 排序左侧数组;
递归深度:3; left=3, right=4, mid=3; 排序左侧数组;
递归深度:4; left=3, right=3
****************递归返回*****************
递归深度:3; 排序右侧数组; 
递归深度:4; left=4, right=4
****************递归返回*****************
递归深度:3; 开始合并数组; 
---------------------------------------
比较前临时数组:[0, 0]
比较[3, 4]号位数字[3, 9]
比较后临时数组:[3, 0]
复制左侧剩余元素:
复制左侧剩余元素后,临时数组:[3, 0]
复制右侧剩余元素:9
复制右侧剩余元素后,临时数组:[3, 9]
---------------------------------------
递归深度:3; 合并后数组; [2, 5, 8, 3, 9, 1]
****************递归返回*****************
递归深度:2; 排序右侧数组; 
递归深度:3; left=5, right=5
****************递归返回*****************
递归深度:2; 开始合并数组; 
---------------------------------------
比较前临时数组:[0, 0, 0]
比较[3, 5]号位数字[3, 1]
比较后临时数组:[1, 0, 0]
复制左侧剩余元素:39
复制左侧剩余元素后,临时数组:[1, 3, 9]
复制右侧剩余元素:
复制右侧剩余元素后,临时数组:[1, 3, 9]
---------------------------------------
递归深度:2; 合并后数组; [2, 5, 8, 1, 3, 9]
****************递归返回*****************
递归深度:1; 开始合并数组; 
---------------------------------------
比较前临时数组:[0, 0, 0, 0, 0, 0]
比较[0, 3]号位数字[2, 1]
比较[0, 4]号位数字[2, 3]
比较[1, 4]号位数字[5, 3]
比较[1, 5]号位数字[5, 9]
比较[2, 5]号位数字[8, 9]
比较后临时数组:[1, 2, 3, 5, 8, 0]
复制左侧剩余元素:
复制左侧剩余元素后,临时数组:[1, 2, 3, 5, 8, 0]
复制右侧剩余元素:9
复制右侧剩余元素后,临时数组:[1, 2, 3, 5, 8, 9]
---------------------------------------
递归深度:1; 合并后数组; [1, 2, 3, 5, 8, 9]
****************递归返回*****************
=======================================
最终数组[1, 2, 3, 5, 8, 9]

第一层拆分: [5, 2, 8] | [3, 9, 1]

第二层拆分: [5, 2] | [8] || [3, 9] | [1]

第三层拆分: [5] | [2] || [8] ||| [3] | [9] || [1]

第四层: 递归返回

第三层合并: [2, 5] | [8] || [3, 9] | [1]

第二层合并: [2, 5, 8] | [1, 3, 9]

第一层合并: [1, 2, 3, 5, 8, 9]

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/30300.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信