详解-归并排序(Mergesort)-C语言Python递归实现

2023-05-16

写在最前

昨天总结了快速排序作为一名自律的“撰笔人”(误),昨天说今天写总结归并排序的文章绝对不鸽(狗头)。

归并排序(Mergesort)

归并排序,跟昨天介绍的快速排序同样都是基于分治(divide and conquer)的思想创建在归并操作(merge)上的一种排序方法。所谓归并操作,是指将两个已经排序好的序列合并成一个序列的操作。因此,基于分治法的思想和归并操作,归并排序的具体步骤如下。

递归法步骤:

  1. 将 待排序序列分成两个子序列,申请两个大小为两个子序列大小的空间,用来存储两个子序列。
  2. 分配两个指针LR,最初位置分别指向两个已经排序好的序列的起始位置。再分配一个指针list,指向待排序序列的起始位置。
  3. 比较两指针指向位置的元素大小,将较小的元素放置待排序序列起始位置,相应指针位置加一(若L指向元素小,则Llist加一,否则Rlist加一)。
  4. 重复步骤3直到子序列的两指针之一到达序列尾。
  5. 将未到尾部序列剩下的元素直接从list当前位置起全部赋给待排序序列。

排序步骤的图示如下:

假设待排序序列为 [ 3 , 5 , 9 , 6 , 2 , 8 , 2 , 6 ] [3,5,9,6,2,8,2,6] [3,5,9,6,2,8,2,6]

过程如下:

完整的代码如下:
C语言版:

#include <stdio.h>
#include <stdlib.h>

void merge(int nums[], int low, int mid, int high);
void mergeSort(int nums[], int low, int high);

int main(){
    int nums[8] = {3,5,9,6,2,8,2,6}; //待排序序列
    mergeSort(nums, 0, 8-1);
    for(int i=0; i<8; i++) //输出排序后的序列
        printf("%d ", nums[i]);
    printf("\n");
    return 0;
}

void merge(int nums[], int low, int mid, int high){
    int n_L, n_R, i, j, k;
    n_L = mid - low + 1; //子序列1的长度
    n_R = high - mid; //子序列2的长度
    int *nums_L = (int*)malloc(sizeof(int)*n_L);
    int *nums_R = (int*)malloc(sizeof(int)*n_R);
    for(i=0; i<n_L; i++) //将待排序序列的前半部分赋给子序列1
        nums_L[i] = nums[low+i];
    for(j=0; j<n_R; j++) //将待排序序列的后半部分赋给子序列2
        nums_R[j] = nums[mid+1+j];
    i = 0, j = 0, k = low;
    while(i < n_L && j < n_R) //两个指针指向两个子序列循环比较
        nums[k++] = nums_L[i] <= nums_R[j] ? nums_L[i++] : nums_R[j++];
    while(i < n_L) //将剩余元素全都赋给待排序序列
        nums[k++] = nums_L[i++];
    while(j < n_R)
        nums[k++] = nums_R[j++];
    free(nums_L);
    free(nums_R);
}

void mergeSort(int nums[], int low, int high){
    int mid;
    if(low < high){
        mid = (low + high) / 2; //均分待排序序列
        mergeSort(nums, low, mid); //排序前半部
        mergeSort(nums, mid+1, high); //排序后半部
        merge(nums, low, mid, high); //归并两个子序列
    }
}

Python3版:

class Solution:
    def merge(self, nums, low, mid, high):
        n_L = mid - low + 1 #子序列1的长度
        n_R = high - mid #子序列2的长度

        nums_L = [0] * n_L
        nums_R = [0] * n_R

        for i in range(n_L): #将待排序序列的前半部赋给子序列1
            nums_L[i] = nums[low+i]
        for j in range(n_R): #将待排序序列的后半部赋给子序列2
            nums_R[j] = nums[mid+1+j]

        i, j, k = 0, 0, low
        while i < n_L and j < n_R: #两个指针指向两个子序列循环比较大小
            if nums_L[i] < nums_R[j]:
                nums[k] = nums_L[i]
                i += 1
            else:
                nums[k] = nums_R[j]
                j += 1
            k += 1

        while i < n_L: #将剩余元素全部赋给待排序列
            nums[k] = nums_L[i]
            i += 1
            k += 1
        while j < n_R:
            nums[k] = nums_R[j]
            j += 1
            k += 1

    def mergeSort(self, nums, low, high):
        if low < high:
            mid = (high + low) // 2  #均分待排序序列
            self.mergeSort(nums, low, mid) #排序前半部
            self.mergeSort(nums, mid+1, high) #排序后半部
            self.merge(nums, low, mid, high) #归并两个子序列

        return nums
        
nums = [1,4,7,2,5,1,4,3,8,6] #待排序子序列

res = Solution().mergeSort(nums, 0, len(nums)-1)
print(res)

如果有哪里理解错的地方欢迎大家留言交流,如需转载请标明出处。

如果你没看懂一定是我讲的不好,欢迎留言,我继续努力。

手工码字码图码代码,如果有帮助到你的话留个赞吧,谢谢。

以上。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

详解-归并排序(Mergesort)-C语言Python递归实现 的相关文章

  • C++库文件解析(conio.h)

    Conio h 控制台输入输出库 该文内容部分参照百度百科 Conio h 在C stanard library ISO C 和POSIX标准中均没有定义 Conio 是Console Input Output的简写 xff0c 其中定义了
  • [Qt] Linux环境下从源码编译Qt

    官网参考 xff1a Qt for Linux X11 Building from Source Qt 5 15 源码下载 xff1a Index of archive qt 5 15 5 15 0 submodules 这里使用的是各个模
  • Collections.max()方法不返回String类型的实际大小

    对于String类型的迭代器是按照字典序列排序的 xff0c 要让Collections max 方法返回实际的大小 xff0c 需要添加比较器 jdk8中对于Collections max xff09 方法有如下的说明 xff1a 样例
  • 简单三步,Github Pages自定义域名开启HTTPS

    登陆域名服务商后台增加 xff0c 域名解析记录 记录值格式为 xff1a username github io 登陆github xff0c 进行仓库设置 添加 自己的域名 xff0c 开启HTTPS
  • FtpClient.storeFile返回false解决方法

    原文地址为 xff1a FtpClient storeFile返回false解决方法 今天在利用FTP将客户端文件存储到服务器端时 xff0c 在调用ftpClient storeFile方法后 xff0c 总是返回false xff0c
  • 上班一个月,我的几点体会

    这篇博文其实在去年就已经在CSDN发过的 后来 xff0c 某次误操作不小心删除了 xff0c 今天找出来重新发一下 我是从3月1号开始上班的 xff0c 今天3月31号 xff0c 刚好一个月结束 xff0c 在这一个月里 xff0c 我
  • 我这一年写的博文

    总结2013 xff0c 展望2014 xff0c gt gt 我的2013年终总结 在苦与乐中成长 下面是我这一年所写的博客 xff0c 主要涉及C xff0c Net Framework xff0c SQL Server xff0c S
  • 我的2013年终总结——在苦与乐中成长

    写在前面 最近正好在三亚旅游 xff0c 空闲下来时 xff0c 便开始进行年终总结 由于去年年末较忙 xff0c 便错过了2012 年的年终总结 xff0c 所以本文将会对 2012 与 2013 两年一起进行总结 说说工作 学生 到 码
  • 走过2014,2015我将继续前行

    写在前面 一转眼 xff0c 一年时光就这么溜走了 在这辞旧迎新之际 xff08 这说法是不是很官方啊 xff0c 呵呵 xff01 xff09 xff0c 我将对即将过去的2014 年进行一番总结 xff0c 并对即将来临的 2015 年
  • C#使用随机数模拟器来模拟世界杯排名(二)

    接上一篇 xff1a C 使用随机数模拟器来模拟世界杯排名 一 C 使用随机数模拟器来模拟世界杯排名 一 斯内科的博客 CSDN博客 我们使用洗牌随机数算法来匹配世界杯对战国家 xff1a 新建洗牌随机数相关类RandomUtil 用于随机
  • Windows Server 2012 R2 服务器密码忘记问题

    解决方法 xff1a 1 准备好一张和当前Windows server 2012R2系统版本和位数相近 xff08 最好相同 xff09 的系统镜像光盘或者ISO文件 2 通过BIOS设置系统从光盘启动 出现安装系统的画面 xff0c 点击
  • Butterknife的替代者ViewBinding的简单使用

    Android自家的 xff0c 又可以省去findviewbyid xff0c 而且Butterknife上大神都已经推荐使用的 xff0c 还有什么理由不去改写呢 build gradle 开启viewBinding功能 android
  • matlab中删除矩阵中的某些行

    方法1 遍历所有行 xff0c 找到满足要求的行tag xff0c 然后调用A a 61 A span class token operator 61 span neighborhood s span class token punctua
  • MySQL 创建新用户并给授权指定的数据库权限

    首先创建用户 span class token comment 低版本数据库 span create user span class token string 39 用户民 39 span 64 span class token strin
  • 如何远程连接Linux服务器

    远程登陆linux xff0c 使用的是ssh协议 windows平台下有putty xff0c Xshell xff0c SecureCRT等工具来远程连接linux服务器 1 putty是一款非常轻量级的SSH连接工具 xff0c 可以
  • 抖音超火3D相册——魔方版(肖战壁纸图片)

    抖音超火3D相册 魔方版 xff08 肖战壁纸图片 xff09 闲来无事 xff0c 写了一个HTML5和CSS的肖战3D相册 xff0c 以下奉上效果图和源代码 xff08 PS xff1a 鼠标触碰可以显示内层六面体照片 xff0c 拖
  • 使用Kotlin开发Android

    Android Studio 中安装 Kotlin Plugin 打开Settings选择Plugins模块 xff0c 搜索Kotlin xff0c 然后选择安装 xff0c 这个需要一个下载的过程 xff0c 下载完安装成功后重启一下A
  • Scrum实践系列之三--敏捷教练的修炼之路

    敏捷教练与项目经理 在被奉为 项目管理圣经 的PMBOK中 xff0c 对项目经理在各阶段的职责有着清晰的界定 xff0c 比如项目经理制定规则 安排进度 监控执行中的各项风险并实时汇报状态 xff0c 等等 然而在敏捷的世界里 xff0c
  • 什么样的人当不好程序员?

    什么样的人当不好程序员 xff1f 2016 01 21 程序员之家 来源 xff1a 36Kr 译文 xff1a http 36kr com p 5042433 html 原文 xff1a https goo gl jLfUFq 软件蚕食
  • apt-get install E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing

    在进行apt get install时一直报错E Unable to fetch some archives maybe run apt get update or try with fix missing 尝试apt get update

随机推荐