十大排序算法之归并排序

news2024/11/28 10:31:58

归并排序

归并排序是包含归并思想的排序方法,它是分治法(Divide and Conquer)的一个典型应用。所谓分治,即将问题“分”(Divide)为更小的问题进行递归求解,再将得到的各个递归结果合并在一起,达到“治”(Conquer)问题的目的,也称“分而治之”。
“分”的阶段可一分为二、一分为三⋯⋯,据此我们也将归并排序分为二路归并、三路归并⋯,此处以二路归并为例进行讲解。

1. 算法思想

先将原数组均分为子序列,一生二,二生四,四生无穷,然后使每个子序列有序,再将两个有序子序列合并为一个有序序列,直到无穷合四,四合二,二合一。

2. 算法步骤

(1)将待排序数组一分为二,再将两个子序列一分为二,成为两个新的待排序数组。
(2)重复步骤(1),直到待排序数组的长度为1。
(3)按原路径将长度为1的两个数组合成一个有序序列,然后一直向前合并,最终就会得到一个完整的有序序列。
归并排序算法的排序步骤如下图所示。
在这里插入图片描述

注意:“分”阶段的结构和完全二又树一模一样,这意味着我们可以使用递归和选代,递归深度为 l o g 2 n log_2n log2n

3. 算法分析

归并排序是一种十分高效的算法,毕竟能利用完全二叉树特性的算法其性能都不会差。从上图中可以看出,分和合的二又树深度均为 l o g 2 n log_2n log2n,而每次分分合合的平均时间复杂度为O(n),二者相乘即为总的平均时间复杂度 O(nlog n),最好和最坏的情况都是一样的。
需要说明的是,归并排序属于稳定排序算法。

4. 算法代码

算法代码如下:
Python

# -*- coding: utf-8 -*-

# 归并排序
def merge (left, right) :
    """
    两个有序子序列的有序合并:
    依次对两个有序列表的最小数进行比较,较小的放入 result中;
    :param left: 左子序列
    :param right: 右子序列
    :return: 左右子序列所合成的有序序列
    """
    # result:存放已经排好顺序的数组
    result=[]
    #如果不符合左右子序列长度均大于0,则说明至少其中的一个数组已无数据
    while len(left) > 0 and len(right)>0:
        # 相等的时候优先把左侧的数放进结果列表,以保证其稳定性
        if left[0] <= right[0]:
            # list.pop (0)为移除并返回列表的第一个元素
            result.append (left.pop (0) )
        else:
            result.append(right.pop(0))
    # 跳出 while 循环后,我们便可以把另一个数组尽数加入 result 后面
    result += left
    result += right
    return result
def merge_sort(array) :
    '''
    无序序列的不断拆分:
    每次均由中间位置进行拆分,不断自我递归调用,直到子序列长度为1
    '''

    # 如果拆分后仅有单个元素,则返回该元素而不再拆分
    if len(array)== 1:
        return array
    #如果有两个及以上元素,则取中间位置进行拆分
    middle = len(array)// 2
    # 拆分后的左侧子串
    array_left = array[:middle]
    #拆分后的右侧子串
    array_right = array[middle:]
    # 对拆分后的左右子序列进行再拆分,直到 len(array) 1
    left = merge_sort(array_left)
    right = merge_sort(array_right)
    # 合并已拆分的左右子序列的同时进行排序并返回排序后的结果
    return merge(left, right)
#调用 merge_sort 函数
print(merge_sort([34,21,13,2,5,1,55,3,1,8]))

Java

  // 合并两个有序子数组的方法
    public static List<Integer> merge(List<Integer> left, List<Integer> right) {
        List<Integer> result = new ArrayList<>();

        while (!left.isEmpty() && !right.isEmpty()) {
            if (left.get(0) <= right.get(0)) {
                result.add(left.remove(0));
            } else {
                result.add(right.remove(0));
            }
        }

        // 将剩余元素全部添加到结果列表中
        while (!left.isEmpty()) {
            result.add(left.remove(0));
        }
        while (!right.isEmpty()) {
            result.add(right.remove(0));
        }

        return result;
    }

    // 归并排序主方法
    public static List<Integer> mergeSort(List<Integer> array) {
        if (array.size() == 1) {
            return array;
        }

        int middle = array.size() / 2;
        List<Integer> arrayLeft = new ArrayList<>(array.subList(0, middle));
        List<Integer> arrayRight = new ArrayList<>(array.subList(middle, array.size()));

        arrayLeft = mergeSort(arrayLeft);
        arrayRight = mergeSort(arrayRight);

        return merge(arrayLeft, arrayRight);
    }
        @Test
        void contextLoads () {
            List<Integer> array = Arrays.asList(34, 21, 13, 2, 5, 1, 55, 3, 1, 8);
            List<Integer> sortedArray = mergeSort(new ArrayList<>(array));
            System.out.println(sortedArray);
        }

5、输出结果

在这里插入图片描述

6. 算法过程分解

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

百面嵌入式专栏(面试题)网络编程面试题

沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇我们将介绍网络编程面试题 。 1、什么是IO多路复用 I/O多路复用的本质是使用select,poll或者epoll函数,挂起进程,当一个或者多个I/O事件发生之后,将控制返回给用户进程。以服务器编程为例,传统的多进程(多线程…

C语言函数递归详解

递归是什么&#xff1f; 递归&#xff0c;顾名思义&#xff0c;就是递推和回归。 递归是一种解决问题的方法&#xff0c;在C语言中&#xff0c;递归就是函数自己调用自己。 #include <stdio.h> int main() {printf("hehe\n");main();//main函数中⼜调⽤了main…

【Web】CVE-2021-22448 Log4j RCE漏洞学习

目录 复现流程 漏洞原理 复现流程 启动HTTP->启动LDAP->执行Log4j vps起个http服务,放好Exploit.class这个恶意字节码 LDAPRefServer作为恶意LDAP服务器 import java.net.InetAddress; import java.net.MalformedURLException; import java.net.URL; import javax.ne…

NLP入门系列—词嵌入 Word embedding

NLP入门系列—词嵌入 Word embedding 2013年&#xff0c;Word2Vec横空出世&#xff0c;自然语言处理领域各项任务效果均得到极大提升。自从Word2Vec这个神奇的算法出世以后&#xff0c;导致了一波嵌入&#xff08;Embedding&#xff09;热&#xff0c;基于句子、文档表达的wor…

Qt程序设计-自定义QLineEdit控件添加鼠标单击事件

本文讲解Qt自定义QLineEdit控件添加鼠标单击事件。 QLineEdit控件默认没有单击事件,但是项目开发中有时需要单击事件,比如单击QLineEdit控件弹出软键盘。具体实现过程如下: 创建项目,在项目中添加一个类,命名为MyLineEdit 输入继承QLineEdit #ifndef MYLINEEDIT_H #defi…

云计算、Docker、K8S问题

1 云计算 云计算作为一种新兴技术&#xff0c;已经在现代社会中得到了广泛应用。它以其高效、灵活和可扩展特性&#xff0c;成为了许多企业和组织在数据处理和存储方面的首选方案。 1.1 什么是云计算&#xff1f;它有哪些特点&#xff1f; 云计算是一种通过网络提供计算资源…

深入理解TCP网络协议(3)

目录 1.前言 2.流量控制 2.阻塞控制 3.延时应答 4.捎带应答 5.面向字节流 6.缓冲区 7.粘包问题 8.TCP异常情况 9.小结 1.前言 在前面的博客中,我们重点介绍了TCP协议的一些属性,有连接属性的三次握手和四次挥手,还有保证数据安全的重传机制和确认应答,还有为了提高效率…

最短编辑距离问题与动态规划----LeetCode 72.编辑距离

动态规划&#xff08;Dynamic Programming, DP&#xff09;是解决复杂问题的一个强大工具&#xff0c;它将问题分解成更小的子问题&#xff0c;并使用这些子问题的解决方案来构建整体问题的解决方案。在深入探讨最短编辑距离问题之前&#xff0c;让我们先理解什么是动态规划&am…

爬取58二手房并用SVR模型拟合

目录 一、前言 二、爬虫与数据处理 三、模型 一、前言 爬取数据仅用于练习和学习。本文运用二手房规格sepc(如3室2厅1卫)和二手房面积area预测二手房价格price&#xff0c;只是练习和学习&#xff0c;不代表如何实际意义。 二、爬虫与数据处理 import requests import cha…

Debian系统显示中文

开发板上的debian默认不显示中文。 安装字体 sudo apt install fonts-wqy-zenhei 安装locals sudo apt install locales &#xff08;无必要&#xff09;设置/etc/locale.gen、设置/etc/locale.conf 运行dpkg-reconfigure locales dpkg-reconfigure locales 可以选择UT…

数字人客服技术预研

技术洞察 引言 在当今数字化时代&#xff0c;不断进步和创新的人工智能&#xff08;AI&#xff09;技术已经渗透到各行各业中。随着AI技术、大模型技术逐步发展&#xff0c;使得数字人的广泛应用成为可能&#xff0c;本文将跟大家一起探讨AI数字人客服的概念、优势、应用场景…

基于Springboot的校园失物招领网站(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的校园失物招领网站&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…

修复wordpress安全漏洞

1. 问题描述&#xff1a; 用wordpress建了一个网站&#xff0c;但是学校反映说存在安全漏洞&#xff0c;通过接口https://xxx.xxx.edu.cn/?rest_route/wp/v2/users/可以访问到一些内容&#xff0c;希望可以关闭这个接口。 2. 解决办法 一共两步 &#xff08;1&#xff09;在fu…

基于深度学习的SSVEP分类算法简介

基于深度学习的SSVEP分类算法简介 1、目标与范畴2、深度学习的算法介绍3、参考文献 1、目标与范畴 稳态视觉诱发电位&#xff08;SSVEP&#xff09;是指当受试者持续注视固定频率的闪光或翻转刺激时&#xff0c;在大脑枕-额叶区域诱发的与刺激频率相关的电生理信号。与P300、运…

Flume多进程传输

1.Flume介绍 Flume 是一种分布式、可靠且可用的服务&#xff0c;用于高效收集、聚合和移动大量日志数据。它具有基于流数据流的简单而灵活的架构。它具有鲁棒性和容错性&#xff0c;具有可调的可靠性机制和许多故障转移和恢复机制。它使用简单的可扩展数据模型&#xff0c;允许…

【自然语言处理】P4 神经网络基础 - 激活函数

目录 激活函数SigmoidTanhReLUSoftmax 本节博文介绍四大激活函数&#xff0c;Sigmoid、Tanh、ReLU、Softmax。 激活函数 为什么深度学习需要激活函数&#xff1f; 博主认为&#xff0c;最重要的是 引入非线性。 神经网络是将众多神经元相互连接形成的网络。如果神经元没有激…

Text Mesh Pro图文混排如何对任何图片都能实现

1&#xff09;Text Mesh Pro图文混排如何对任何图片都能实现 2&#xff09;Unity iOS平台的小图占用特别大的内存 3&#xff09;只在编辑器内&#xff0c;纹理不开启Read&Write情况下&#xff0c;如何获取纹理所有颜色值 4&#xff09;准备在海外发行游戏&#xff0c;有哪些…

微服务入门篇:Nacos注册中心(Nacos安装,快速入门,多级存储,负载均衡,环境隔离,配置管理,热更新,集群搭建,nginx反向代理)

目录 1.Nacos安装1.官网下载2.解压到本地3.启动nacos 2.Nacos快速入门1.在父工程中导入nacos依赖2.给子项目添加客户端依赖3.修改对应服务的配置文件4.启动服务&#xff0c;查看nacos发现情况 3.Nacos服务多级存储模型4.NacosRule负载均衡5. 服务实例的权重设置6.环境隔离&…

【SAR成像】基于RD、CS和ωk算法的合成孔径雷达成像算法原理与实现

基于RD、CS和ωk算法的合成孔径雷达成像算法实现 前言SAR基本概念雷达获取数据的几何关系低斜视角下的回波信号模型 RADARSAT-1主要参数数据预处理数据读取与再封装数据补零 成像算法坐标轴的产生RD算法距离压缩距离徙动矫正方位压缩 CS算法第一次相位相乘 变标后的信号第二次相…

Unity类银河恶魔城学习记录1-11 PlayerPrimaryAttack P38

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili Player.cs using System.Collections; using System.Collections.Generic…