【通俗易懂-动态图解析】归并排序、计数排序

2023-11-06

编程TWO 编程小兔崽 今天

 

归并排序

 

和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是O(n log n)的时间复杂度。代价是需要额外的内存空间。

 

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。归并排序是一种稳定的排序方法。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。

 

算法描述

把长度为n的输入序列分成两个长度为n/2的子序列;

对这两个子序列分别采用归并排序;

将两个排序好的子序列合并成一个最终的排序序列。

 

代码:

 

代码:

#include<stdio.h>
#include<malloc.h>
void mergerSort(int *a1, int *a2, int **a3, 
int count1, int count2, int *count3);
void showArray(int *a3, int count);
void showArray(int *a3, int count)
{
    int i;

    for(i = 0; i < count; i++)
    {
        printf("%d ", a3[i]);
    }

    printf("\n");
 }
 void mergerSort(int *a1, int *a2, 
    int **a3, int count1, int count2, int *count3)
{
    int count;
    int i = 0;
    int j = 0;
    int n = 0;

    count = *count3 = count1 + count2;
    *a3 = (int *)malloc(sizeof(int) * count);
    //以下的都是<,因为传过来的是数组长度;
    while(i < count1 && j < count2)
    {
        if(a1[i] < a2[j])
        {
            (*a3)[n++] = a1[i];
            i++;
        }
        else if(a1[i] == a2[j])
        {
            (*a3)[n++] = a1[i];
            (*a3)[n++] = a2[j];
            i++;
            j++;
        }
        else
        {       //刚才写程序else(a1[i] > a2[j]),后发现else语句后面是没有条件的!!!
            (*a3)[n++] = a2[j];
            j++;
        }
    }

    while(i < count1)
    {
        (*a3)[n++] = a1[i];
        i++;
    }
    while(j < count2)
    {
        (*a3)[n++] = a2[j];
        j++;
    }
   }
/* 
归并排序核心算法就是:将已经排好序的2个数组进行最终的排序过程;
*/void main(void)
{
    int a1[] = {1, 3, 5, 7};
    int a2[] = {0, 2, 4, 6, 8, 9, 10};
    int count1 = sizeof(a1)/sizeof(int);
    int count2 = sizeof(a2)/sizeof(int);
    int *a3 = NULL;
    int count3 = 0;

    mergerSort(a1, a2, &a3, count1, count2, &count3);
    showArray(a3, count3);
    free(a3);
   }

 

算法分析

最佳情况:T(n) = O(n)  最差情况:T(n) = O(nlogn)  平均情况:T(n) = O(nlogn)

 

计数排序:

计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。 作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。

计数排序(Counting sort)是一种稳定的排序算法。计数排序使用一个额外的数组C,其中第i个元素是待排序数组A中值等于i的元素的个数。然后根据数组C来将A中的元素排到正确的位置。它只能对整数进行排序。

 

算法描述

找出待排序的数组中最大和最小的元素;

统计数组中每个值为i的元素出现的次数,存入数组C的第i项;

对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加);

反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1。

 

 

代码:

#include<stdio.h>
void countSort(int *a, int count);
void showArray(int *a, int count);
void showArray(int *a, int count)
{
    int i;

    for(i = 0; i < count; i++)
    {
        printf("%d ", a[i]);
    }
    printf("\n");
 }
 void countSort(int *a, int count)
 {
    int b[10] = {0};
    int *c;
    int i;

    c = (int *)malloc(sizeof(int) * count);
    for(i = 0; i < count; i++)
    {
        b[a[i]]++;
    }
    for(i = 1; i < 10; i++)
    {
        b[i] += b[i-1];
    }

    for(i = count-1; i >= 0; i--)
    {
        c[b[a[i]]-1] = a[i];
        b[a[i]]--;
    }

    for(i = 0; i < count; i++)
    {
        a[i] = c[i];
    }

    free(c);
  }
  void main(void)
  {
    int a[] = {2, 4, 7, 2, 1, 0, 9};
    int count = sizeof(a)/sizeof(int);

    countSort(a, count);
    showArray(a, count);
   }

 

算法分析

当输入的元素是n 个0到k之间的整数时,它的运行时间是 O(n + k)。计数排序不是比较排序,排序的速度快于任何比较排序算法。由于用来计数的数组C的长度取决于待排序数组中数据的范围(等于待排序数组的最大值与最小值的差加上1),这使得计数排序对于数据范围很大的数组,需要大量时间和内存。

最佳情况:T(n) = O(n+k)  最差情况:T(n) = O(n+k)  平均情况:T(n) = O(n+k)

推荐阅读:

【通俗易懂-动态图解析】冒泡排序、选择排序

【通俗易懂-动态图解析】插入排序、快速排序

长按2秒识别二维码关注公众号

欢迎把我推荐给你的朋哟

每天进步一点点,如果有用给点个赞

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

【通俗易懂-动态图解析】归并排序、计数排序 的相关文章

  • 标准的遗传算法求函数最大值

    最近看了下遗传算法 刚看了一点 就觉得手痒 非要把程序编制出来看看效果 我现在总认为那些理论再高深 无法用计算机实现就是空话 呵呵 下面是我调试了好久的代码 无赖没有学过数据结构 算法 程序写的很差 单效果还是出来了 高兴 和大家共同分享下
  • TopK问题的三种解法

    TopK问题是指从n个数据中取前K个数据 在生活中的应用也有很多 如游戏中xxx的排行榜前10名等 在这篇博客中我将主要利用堆去解决TopK问题 堆排序 首先我们需要建一个堆 然后我们再进行堆排序 排好序后直接取前K个就可以了 需要注意的是
  • 动态规划系列之「最长递增子序列的个数」

    673 最长递增子序列的个数 给定一个未排序的整数数组 找到最长递增子序列的个数 示例 1 输入 1 3 5 4 7 输出 2 解释 有两个最长递增子序列 分别是 1 3 4 7 和 1 3 5 7 示例 2 输入 2 2 2 2 2 输出
  • 有限状态自动机

    1 什么是有限状态自动机 1 1什么是计算 维基百科定义 计算 英语 Calculation 是一种将 单一或多个的输入值 转换为 单一或多个的结果 的一种思考过程 可以简单理解为给出一个问题得到一个答案的过程 如下图所示日常生活比较常见计
  • JavaScript 算法系列---动态规划

    很久之前接触过这样一道题目 总共有十层阶梯 从1层开始往上爬 每次可以上1层或者2层 问到10层总共有多少种方法 思路 这个问题就是动态规划的一个经典例子 所谓动态规划 就是把复杂的问题进行拆解 拆解成一个个子问题 而这类问题最后非常适合使
  • 数据结构与算法:去除重复字母

    给你一个仅包含小写字母的字符串 请你去除字符串中重复的字母 使得每个字母只出现一次 需保证返回结果的字典序最小 要求不能打乱其他字符的相对位置 示例 1 输入 bcabc 输出 abc 示例 2 输入 cbacdcbc 输出 acdb 解题
  • 深入分析 (迪杰斯特拉算法) Dijkstra 算法实现原理

    迪杰斯特拉 Dijkstra 算法是典型最短路径算法 用于计算一个节点到其他节点的最短路径 它的主要特点是以起始点为中心向外层层扩展 广度优先搜索思想 直到扩展到终点为止 基本思想 通过Dijkstra计算图G中的最短路径时 需要指定起点s
  • 数据结构-判断平衡二叉树(java)

    判断平衡二叉树 题目 力扣110题 解题思路 1 首先理解平衡二叉树的定义 使用Map存储每个节点的高度 2 求得当前节点的左右子树高度 若Map中左右子树高度已经求过 直接取得 若没有 通过递归计算高度并存入Map中 3 左右子树高度差
  • 【STL详解】stack

    文章目录 前言 一 STL 二 stack 1 stack的创建 2 stack相关方法 3 如何对satck进行排序 前言 本篇文章将总结SLT stack 以及其常用方法 一 STL STL 是 Standard Template Li
  • 数据结构-二分搜索树转双向链表(Java)

    二分搜索树转双向链表 牛客JZ36 题目 思路 1 对二分搜索树进行中序遍历 2 将二分搜索树左节点和根节点相连接 右节点和根节点相连接 遍历左子树 连接 左子树尾部不为空 leftTail right pRootOfTree pRootO
  • 环形链表II

    环形链表II 给定一个链表的头节点 head 返回链表开始入环的第一个节点 如果链表无环 则返回 null 如果链表中有某个节点 可以通过连续跟踪 next 指针再次到达 则链表中存在环 为了表示给定链表中的环 评测系统内部使用整数 pos
  • 数据结构—判断一棵二叉树是否是完全二叉树(java)

    判断一棵二叉树是否是完全二叉树 一 完全二叉树的三种节点 完全二叉树有右树必有左树 节点编号和满二叉树一一对应 1 度为2的节点有n个 2 度为1的节点只能有1个 3 度为0的节点有n个 二 具体思路 1 分两个阶段 第一阶段所有节点都有左
  • 二叉树-判断另一棵树的子树(Java)

    另一棵的子树 力扣572题 题目 给你两棵二叉树 root 和 subRoot 检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树 如果存在 返回 true 否则 返回 false 二叉树 tree 的一棵子树包括 t
  • 二分查找(Binary Search) 常见问题解决方法总结

    缘由 今天浏览 何登成的技术博客 无意中发现了写的blog 二分查找 Binary Search 需要注意的问题 以及在数据库内核中的实现 随想总结下二分查找的常见问题 问题背景 今年的实习生招聘考试 我出了一道二分查找 Binary Se
  • 【Leetcode刷题笔记之链表篇】142. 环形链表 II

    博客主页 大家好我叫张同学 欢迎点赞 收藏 留言 欢迎讨论 本文由 大家好我叫张同学 原创 首发于 CSDN 精品专栏 不定时更新 数据结构 算法 做题笔记 C语言编程学习 精品文章推荐 C语言进阶学习笔记 三 字符串函数详解 1 爆肝吐血
  • 删除链表元素详解版(Java)

    目录 题目 1 一般方法 2 虚拟头节点法 3 递归法 题目 Leetcode203题 移除链表元素 给你一个链表的头节点 head 和一个整数 val 请你删除链表中所有满足 Node val val 的节点 并返回 新的头节点 1 一般
  • 七大经典排序算法总结【详解】

    排序算法的分类 插入排序 选择排序 交换排序 归并排序 具体分类如图所示 这七种排序算法在我们生活中应用非常广泛 所用的场景各有不同 他的时间复杂度和空间复杂度也是不同的 一 插入排序 初始数据越接近有序 时间效率越高 1 直接插入排序 直
  • 数据结构与算法:KMP模式匹配算

    KMP模式匹配算法原理 如果主串S abcdefgab 其实还可以更长一些 我们就省略掉只保留前9位 我们要匹配的T abcdex 那么如果用BF算法的话 前5个字母 两个串完全相等 直到第6个字母 f 与 x 不等 如图5 7 1的 所示
  • 排列数组使得偶数在奇数的前面

    Name ReorderOddEven c Author 齐保元 Version Copyright Your copyright notice Description Hello World in C Ansi style include
  • LSM详解

    关于LSM结构的相关介绍 这篇文章比较好 特此纪录一下https yq aliyun com articles 767772

随机推荐

  • LeetCode:118(Python)—— 杨辉三角(简单)

    杨辉三角 概述 给定一个非负整数 numRows 生成 杨辉三角 的前 numRows 行 在 杨辉三角 中 每个数是它左上方和右上方的数的和 输入 numRows 5 输出 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 输入
  • 超经典!分割任务数据集介绍。

    文章目录 前言 一 IRSTD 1k 二 Pascal VOC2012 1 数据简介 2 分割任务数据集介绍 三 iSAID 总结 前言 在探索网络的过程中 比较基础和重要的工作是了解数据 今天来总结下我目前使用过的分割任务数据集 本博文将
  • Linux进阶_DNS服务和BIND之实战案例篇

    成功不易 加倍努力 1 实战案例 实现DNS正向主服务器 2 实战案例 实现DNS从服务器 3 实战案例 实现DNS forward 缓存 服务器 4 实战案例 利用view实现智能DNS 5 实战案例 综合案例 实现Internet 的D
  • 【linux多线程(四)】——线程池的详细解析(含代码)

    目录 什么是线程池 线程池的应用场景 线程池的实现 线程池的代码 C linux线程 壹 初识线程 区分线程和进程 线程创建的基本操作 线程 二 互斥量的详细解析 线程 三 条件变量的详细解析 什么是线程池 线程池是一种线程使用模式 它是将
  • java 栅栏_Java并发基础-栅栏(CountDownLatch)与闭锁(CyclicBarrier)

    1 闭锁CountDownLatch 闭锁CountDownLatch用于线程间的同步 它可以使得一个或者多个线程等待其它线程中的某些操作完成 它有一个int类型的属性count 当某个线程调用CountDownLatch对象的await方
  • android获取各种系统路径的方法

    android获取各种系统路径的方法 整理了一些安卓开发中可能会用到的各种路径的获取方法 欢迎评论 通过Environment获取的Environment getDataDirectory getPath 获得根目录 data 内部存储路径
  • Spring Boot + 阿里OSS实现图片上传,返回预览的地址,实现图片预览

    阿里OSS实现图片上传 返回预览地址 注册阿里OSS 首先进入阿里云的官网 https www aliyun com 紧接着点击首页上的立即开通 点击这个创建一个bucket 其余的默认就可以 可以根据自己的实际需求去写 使用代码操作阿里O
  • Redis AOF和RDB

    Redis AOF和RDB Redis是内存型数据库 为了保证数据在断电后不会丢失 需要将内存中的数据持久化到硬盘上 RDB持久化 将某个时间点的所有数据都存放到硬盘上 可以将快照复制到其他服务器从而创建具有相同数据的服务器副本 如果系统发
  • vue不是内部或外部命令,也不是可运行的程序

    使用vue脚手架初始化vue项目时 总是报 vue不是内部或外部命令 也不是可运行的程序 这样的错误 检查基础环境是否具备 1 node v查看版本 已经安装 2 npm v查看版本 已经安装 3 node 系统环境变量已经设置 于是乎 查
  • Error: Cannot fit requested classes in a single dex file (# methods: 65948 > 65536) 解决方法

    Error Cannot fit requested classes in a single dex file methods 65948 gt 65536 解决方法 最近写项目 写着写着运行时突然就报错了 运行不起来了 报错如下 Erro
  • 【django】admin后台管理的坑

    自定义的主键 必须要在fields或者fieldsets里 但是默认添加的或者自主添加的autofield字段可以不在admin页面里添加 保存时会自动添加
  • A股投资日历

    A股投资日历 12月2日 国11月非农就业报告 21 30 中证AAA综合债指数系列 8条 发布 2022中国 博鳌 国际黄金市场年度大会举办 影响 宏观 债券 黄金 12月2 3日 第四届大宗商品金融服务创新锋会 影响 大宗商品 12月2
  • Linux下嵌入式程序仿真调试(GDB)(二)

    目录 目录 前言 Ubuntu下Qt的GDB环境搭建未成功 Qt5的设置 命令行调试问题记录 总结 链接地址 前言 Linux下嵌入式程序仿真调试 GDB 一 主要介绍了GDB交叉调试环境的搭建过程 本想把交叉编译好的gdb程序放置到Qt中
  • SpringBean的自动装配运行原理

    SpringBean的自动装配运行原理 引言 在现代的软件开发领域中 快速且灵活地处理依赖关系是至关重要的 Spring框架以其强大的依赖注入功能 使得开发者能够轻松管理各种对象之间的依赖关系 其中 自动装配是Spring框架中一项重要的功
  • (Oracle功能篇) Oracle 数据库连接池

    使用 proxool 0 9 1 zip http ncu dl sourceforge net project proxool proxool 0 9 1 proxool 0 9 1 zip 相关代码 package yerasel im
  • SpringBoot+Mybatis 整合 xml配置使用+免xml使用

    SpringBoot作为现在非常流行的微服务框架 Mybatis作为现在非常流行的ORM框架 他们整合在一起是不是会产生火花呢 今天就搭建一个SpringBoot Mybatis的微服务开发环境 IEDA JDK1 8首先我们先创建个mav
  • h3c 生成树协议及stp配置命令

    STP 作用 1 通过阻断冗余链路来消除桥接网络中可能存在的路径回环 2 当前路径发生故障时 激活冗余备份链路 恢复网络连通性 STP Spanning Tree Protocol 生成树协议 是用于在局域网中消除数据链路层物理环路的协议
  • hive配置优化

    错误描述 执行 hive 任务报错 highlighting text 版本 Hive 2 2 0 Hadoop 2 7 6 Exit code is 143 Container exited with a non zero exit co
  • DoubleDQN的理论基础及其代码实现【Pytorch + Pendulum-v0】

    Double DQN 理论基础 普通的 DQN 算法通常会导致对值的过高估计 overestimation 传统 DQN 优化的 TD 误差目标为 r max
  • 【通俗易懂-动态图解析】归并排序、计数排序

    编程TWO 编程小兔崽 今天 归并排序 和选择排序一样 归并排序的性能不受输入数据的影响 但表现比选择排序好的多 因为始终都是O n log n 的时间复杂度 代价是需要额外的内存空间 归并排序是建立在归并操作上的一种有效的排序算法 该算法