归并排序(看了就会)

news2024/10/6 18:22:00

目录

  • 概念
    • 1. 基本思想
    • 2. 实现逻辑
    • 3. 复杂度分析
    • 4、代码

概念

归并排序,是创建在归并操作上的一种有效的排序算法。算法是采用分治法(Divide and Conquer)的一个非常典型的应用,且各层分治递归可以同时进行。归并排序思路简单,速度仅次于快速排序,为稳定排序算法,一般用于对总体无序,但是各子项相对有序的数列。
在这里插入图片描述

1. 基本思想

归并排序是用分治思想,分治模式在每一层递归上有三个步骤:
● 分解(Divide):将n个元素分成个含n/2个元素的子序列。
● 解决(Conquer):用合并排序法对两个子序列递归的排序。
● 合并(Combine):合并两个已排序的子序列已得到排序结果。

2. 实现逻辑

递归法
① 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
② 设定两个指针,最初位置分别为两个已经排序序列的起始位置
③ 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
④ 重复步骤③直到某一指针到达序列尾
⑤ 将另一序列剩下的所有元素直接复制到合并序列尾
在这里插入图片描述

上图中首先把一个未排序的序列从中间分割成2部分,再把2部分分成4部分,依次分割下去,直到分割成一个一个的数据,再把这些数据两两归并到一起,使之有序,不停的归并,最后成为一个排好序的序列。

在这里插入图片描述

3. 复杂度分析

在这里插入图片描述

平均时间复杂度:O(nlogn)
最佳时间复杂度:O(nlogn)
最差时间复杂度:O(nlogn)
空间复杂度:O(n)
稳定性:稳定
不管元素在什么情况下都要做这些步骤,所以花销的时间是不变的,所以该算法的最优时间复杂度和最差时间复杂度及平均时间复杂度都是一样的为:O( nlogn )
归并的空间复杂度就是那个临时的数组和递归时压入栈的数据占用的空间:n + logn;所以空间复杂度为: O(n)。
归并排序算法中,归并最后到底都是相邻元素之间的比较交换,并不会发生相同元素的相对位置发生变化,故是稳定性算法。

4、代码

在这里插入图片描述

package Sort;

import java.util.Arrays;

/**
 * @BelongsProject: JAVAtest
 * @BelongsPackage: Sort
 * @Author: 
 * @CreateTime: 2023-05-01  10:18
 * @Description: TODO
 * @Version: 1.0
 */
public class divideAndConquer {
    public static void main(String[] args) {
        // 定义待排序数组
        int[] arr = {14,12,15,13,11,16};
        //新建一个临时数组存放
        int[] tmp = new int[arr.length];
        // 归并排序
        mergeSort(arr, 0, arr.length - 1, tmp);
        for (int i = 0; i < arr.length; i++) {
            // 归并排序
            System.out.print(arr[i] + " ");
        }
    }

    public static void mergeSort(int[] arr, int low, int high, int[] tmp) {
        if (low < high) {
            // 求中间位置,用于将数组拆分成两部分
            int mid = (low + high) / 2;
            //对左边序列递归划分
            mergeSort(arr, low, mid, tmp);
            //对右边序列进行递归划分
            mergeSort(arr, mid + 1, high, tmp);
            //合并两个有序序列
            merge(arr, low, mid, high, tmp);
        }
    }

    public static void merge(int[] arr, int low, int mid, int high, int[] tmp) {
        // 用于遍历 tmp 数组的指针
        int i = 0;
        //左边序列和右边序列起始索引
        int j = low, k = mid + 1;
        // 比较左右两个有序数组的元素,并按大小依次放入 tmp 数组中
        while (j <= mid && k <= high) {
             //左半区第一个元素小于右半区第一个元素
            if (arr[j] < arr[k]) {
                //接着往后继续比
                tmp[i++] = arr[j++];
            }
            //右半区第一个元素更小,先放右半区第一个元素
            else {
                tmp[i++] = arr[k++];
            }
//            // 输出排序过程中数组 arr 的变化
            System.out.println(Arrays.toString(arr));
        }
        //若左边序列还有剩余,则将其全部拷贝进tmp[]while (j <= mid) {
            tmp[i++] = arr[j++];
        }

        while (k <= high) {
            tmp[i++] = arr[k++];
        }
        // 将排好序的 tmp 数组复制到原数组 arr 中

        for (int t = 0; t < i; t++) {
            arr[low + t] = tmp[t];
        }
    }
}

拓展:
递归和迭代
递归和迭代都是解决问题的方法。递归是通过不断调用自身来解决问题,迭代是通过重复执行相同的操作来解决问题。
递归和迭代的主要区别在于它们的实现方式和执行过程。在递归中,程序通过调用自身来解决问题。递归函数将问题划分为子问题,并将这些子问题交给自身来解决。递归函数必须有一个终止条件,否则它将无限地调用自身,导致程序崩溃。
在迭代中,程序通过重复执行相同的操作来解决问题。迭代通常使用循环结构来实现。在每次迭代中,程序会执行相同的操作,直到达到问题的解决条件为止。迭代的优点是可以使用较少的内存,而且通常比递归更快。
递归和迭代都有各自的优点和缺点。递归通常比较容易理解和实现,但是由于每次递归都会创建新的函数调用栈,因此会消耗较多的内存。迭代通常需要较少的内存,但是实现起来可能比较困难,特别是对于复杂的算法来说。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/492981.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

智头条|欧盟达成《人工智能法》协议,全球前沿科技齐聚AWE 2023

行业动态 华为云联手多方推进数字化&#xff0c;软通动力深度参与 华为云宣布启动“‘百城万企’应用现代化中国行”&#xff0c;旨在推动应用现代化进程、助力数字中国高质量落地。软通动力是该行动的参与者之一&#xff0c;共同探索符合区域特点、产业趋势、政企现状的数字化…

Python进阶(Linux操作系统)

一&#xff0c;操作系统 1.1&#xff0c;Linux系统基础操作 1.2&#xff0c;linux进程与线程 1.2.1并发&#xff0c;并行 &#xff08;1&#xff09;并发&#xff1a;在一段时间内交替的执行多个任务&#xff1a;对于单核CPU处理多任务&#xff0c;操作系统轮流让让各个任务…

BasicVSR++代码解读(总体介绍)

本文代码主要来自于OpenMMLab提供的MMEditing开源工具箱中的BasicVSR代码。第一部分的解读主要是针对每一个部分是在做什么提供一个解释&#xff0c;便于后续细读每一个块的细节代码。 &#xff08;1&#xff09;导入库     basicvsr_plusplus_net中主要继承了torch,mmcv,m…

信号的产生——线性调频函数

信号的产生——线性调频函数 产生线性调频扫频信号函数chirp的调用格式如下&#xff1a; &#xff08;1&#xff09;y chirp(t,f0, t1,f1) 功能&#xff1a;产生一个线性&#xff08;频率随时间线性变化&#xff09;信号&#xff0c;其时间轴设置由数组t定义。时刻0的瞬间频…

SpringBoot的配置文件、日志文件

一、配置文件&#xff08; .properties、.yml&#xff09; 1、.properties 配置文件 1.1、格式 1.2、基本语法 1.2.1、如&#xff1a;一般配置&#xff08;以键值的形式配置的&#xff0c;key 和 value 之间是以“”连接的。&#xff09; 1.2.2、如&#xff1a;自定义配置&a…

tcc-transaction 源码分析

tcc介绍 tcc介绍查看我之前的文章&#xff1a; https://caicongyang.blog.csdn.net/article/details/119721282?spm1001.2014.3001.5502 tcc-transaction 介绍&#xff1a; http://mengyun.org/zh-cn/index.html 本文基于2.x 最新版本:https://github.com/changmingxie/tcc…

以京东为例,分析优惠价格叠加规则

一、平行优惠计算原则 1、什么是“平行式门槛计算规则”&#xff1f; 平行式门槛计算规则&#xff0c;即每一层级优惠都直接根据商品的单品基准价来计算是否符合门槛&#xff0c;店铺/平台促销、优惠券类优惠之间是并列关系&#xff0c;只要单品基准价或单品基准价总和&#x…

c++(类和对象中)

【本节目标】 1. 类的6个默认成员函数 2. 构造函数 3. 析构函数 4. 拷贝构造函数 5. 赋值运算符重载 6. const成员函数 7. 取地址及const取地址操作符重载 目录 1、类的6个默认成员函数 2、构造函数 2.1概念 2.2特性 3.析构函数 3.1概念 3.2特性 4.拷贝构造函数…

Kafka生产者

一、生产者发送流程 在消息发送的过程中&#xff0c;涉及到了两个线程——main 线程和 Sender 线程。在 main 线程中创建了一个双端队列 RecordAccumulator。main 线程将消息发送给 RecordAccumulator&#xff0c;Sender 线程不断从 RecordAccumulator 中拉取消息发送到 Kafka …

网络应用基础 ——(2023新星计划文章二)

一&#xff0c;TCP/UDP报头 1.1TCP报文头部详解 Source port:源端口号与Destination port目标端口号&#xff1a; 在TCP&#xff08;传输控制协议&#xff09;协议中&#xff0c;源端口和目标端口字段用于标识通信会话的端点。 &#xff08;1&#xff09;源端口是一个16位字段…

LeetCode 1206. 实现跳表

不使用任何库函数&#xff0c;设计一个跳表。 跳表是在 O(log(n)) 时间内完成增加、删除、搜索操作的数据结构。跳表相比于树堆与红黑树&#xff0c;其功能与性能相当&#xff0c;并且跳表的代码长度相较下更短&#xff0c;其设计思想与链表相似。 例如&#xff0c;一个跳表包…

3.数据查询(实验报告)

目录 一﹑实验目的 二﹑实验平台 三﹑实验内容和步骤 四﹑命令(代码)清单 五﹑调试和测试清单 一﹑实验目的 掌握使用Transact-SQL的SELECT语句进行基本查询的方法&#xff1b;掌握使用SELECT语句进行条件查询的方法&#xff1b;掌握SELECT语句的GROUP BY、ORDER BY以及UN…

MX6U根文件系统配置

编译 BusyBox 构建根文件系统 /home/ /linux/nfs mkdir rootfs tar -vxjf busybox-1.29.0.tar.bz2 依照自己的交叉编译 不然会出错 配置好 busybox 以后就可以编译了&#xff0c;我们可以指定编译结果的存放目录&#xff0c;我们肯定要将编 译结果存放到前面创建的 rootfs 目录…

(leetcode)66. 加一 67. 二进制求和(详解)

目录 66. 加一 思路 代码 67. 二进制求和 思路 代码 66. 加一 给定一个由 整数 组成的 非空 数组所表示的非负整数&#xff0c;在该数的基础上加一。 最高位数字存放在数组的首位&#xff0c; 数组中每个元素只存储单个数字。 你可以假设除了整数 0 之外&#xff0c;这…

7个最好的WordPress LMS在线学习管理系统比较

您是否正在为您的 WordPress 网站寻找最好的 LMS 在线学习管理系统插件&#xff1f; 学习管理系统 (LMS) 插件允许您创建和运行类似 Udemy 和 LearnDesk 等在线课程。一个完美的 WordPress LMS 插件拥有您管理在线课程、运行和评分测验、接受付款等所需的一切。 在本文中&…

【MySql】数据库 select 进阶

数据库 数据库表的设计ER 关系图三大范式 聚合函数与分组查询聚合函数 (count、sum、avg、max、min)分组查询 group by fields....having....(条件) 多表联查内连接外连接&#xff08;左连接&#xff0c;右连接&#xff09;自连接子查询合并查询 UNION 数据库表的设计 ER 关系…

在Centos中metabase安装与配置(bi工具)

1 metabase介绍 metabase是一款开源的BI分析工具&#xff0c;开发语言clojureReact为主、也有高阶的收费版。 官网&#xff1a;https://www.metabase.com/ 可以利用Metabase进行数据分析&#xff0c;数据可视化&#xff0c;报表生成等。开源地址&#xff1a;https://github.co…

(五)【平衡小车制作】位置式PID、直立环与速度环概念

声明&#xff1a;本博客是B站视频【天下行走的平衡小车视频】的笔记 一、PID控制算法概念 PID控制&#xff0c;即为对偏差进行比例、积分和微分控制。由三个元素构成:比例&#xff08;P&#xff09;&#xff0c;积分&#xff08;I&#xff09;&#xff0c;微分&#xff08;D&…

Linux系统应用编程(六)Linux网络编程(下篇)

本篇主要内容&#xff1a; 一、Linux的文件描述符二、多路IO转接&#xff08;上&#xff09;1.基础版多路IO转接select▶ 关于select( )函数▶ select( )改写上篇案例 2.加强版多路IO转接poll3.顶配版多路IO转接epoll▶ epoll相关函数&#xff08;1&#xff09;创建监听红黑树&…

重装系统后,MySQL install错误,找不到dll文件,或者应用程序错误

文章目录 1.找不到某某dll文件2.mysqld.exe - 应用程序错误使用DX工具直接修复 1.找不到某某dll文件 由于找不到VCRUNTIME140_1.dll或者MSVCP120.dll&#xff0c;无法继续执行代码&#xff0c;重新安装程序可能会解决此问题。 在使用一台重装系统过的电脑&#xff0c;再次重新…