【数据结构与算法】第12课—数据结构之归并排序

文章目录

  • 1. 归并排序
  • 2. 计数排序
  • 3. 排序算法复杂度及稳定性分析
    • 在这里插入图片描述

1. 归并排序

  • 分治法(Divide and Conquer)是一种重要的算法设计策略,其核心思想是将一个复杂的大问题分解为若干个小规模的子问题,递归地解决这些子问题,并将它们的解合并起来以得到原始问题的解。
  • 而归并排序正是分治法的一个典型应用
  • 归并排序的思想:首先将一个序列分为两个子序列,再将两个子序列分为4个子序列,直到每个元素都各为一个序列,则不再继续分,然后合并子序列,将子序列开始有序合并,最终合并成一个有序的序列,它本质还是递归
  • 接下来我将用图示的方法来帮助大家理解

在这里插入图片描述


在这里插入图片描述


  • 代码
//归并排序子函数
void _MergeSort(int* arr, int left, int right, int* tmp)
{//如果首元素下标大于等于尾元素下标if (left >= right){return;}//根据中间值二分int mid = left + (right - left) / 2;//左边序列[left,mid]  右边序列[mid+1,right]_MergeSort(arr, left, mid, tmp);//分解左子序列_MergeSort(arr, mid + 1, right, tmp);//分解右子序列//合并两个有序序列int begin1 = left, end1 = mid;int begin2 = mid + 1, end2 = right;int index = begin1;while (begin1 <= end1 && begin2 <= end2){//如果第一个序列的首元素小于第二个序列的首元素if (arr[begin1] < arr[begin2]){tmp[index++] = arr[begin1++];//赋完值都往后走}//如果第一个序列的首元素大于第二个序列的首元素else{tmp[index++] = arr[begin2++];//赋完值都往后走}}//此时若第一个序列还有元素未放入tmp,直接全部放入tmpwhile (begin1 <= end1){tmp[index++] = arr[begin1++];}//此时若第二个序列还有元素未放入tmp,直接全部放入tmpwhile (begin2 <= end2){tmp[index++] = arr[begin2++];}//最后将新建的数组tmp赋给arrfor (int i = left; i <= right; i++){arr[i] = tmp[i];}
}//归并排序
void MergeSort(int* arr, int sz)
{//创建tmp函数用来接收合并的有序数组int* tmp = (int*)malloc(sizeof(int) * sz);if (tmp == NULL){perror("malloc fail!\n");exit(1);}_MergeSort(arr, 0, sz - 1, tmp);free(tmp);tmp = NULL;
}

2. 计数排序

  • 计数排序又称为鸽巢原理,是对哈希直接定址法的变形应用。 操作步骤:
  • 1)统计相同元素出现次数
    2)根据统计的结果将序列回收到原来的序列中

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


  • 代码
//计数排序
void CountSort(int* arr, int sz)
{int max = arr[0], min = arr[0];//默认为首元素//找最大、最小数for (int i = 0; i < sz; i++){if (arr[i] > max){max = arr[i];}if (arr[i] < min){min = arr[i];}}//计数int range = max - min + 1;//count数组大小//calloc申请内存会自动将所有元素默认设置为0int* count = (int*)calloc(range, sizeof(int));if (count == NULL){perror("malloc fail!\n");exit(1);}for (int i = 0; i < sz; i++){count[arr[i]-min]++;//对应的count数组元素++}//排序int index = 0;//arr数组下标//遍历count数组,找对应元素出现的次数for (int i = 0; i < range; i++){//将count数组对应元素放入arr数组while (count[i]--){arr[index++] = i + min;}}//释放内存free(count);count = NULL;
}
  • 计数排序的时间复杂度是O(n+range)
  • 计数排序的空间复杂度是O(range)
  • 计数排序有一定的局限性,当数组中的数据差值较大时,会造成空间的极大浪费,此时计数排序便不再适用,因此它只适用于元素之间差值较小的序列

3. 排序算法复杂度及稳定性分析

  • 稳定性:对于含有相同数据的序列,排序前后不改变他们的相对位置,则代表该算法稳定,否则表示该排序算法不稳定

在这里插入图片描述


  • 各种排序算法的时间复杂度

在这里插入图片描述

  • 各种排序性能测试

在这里插入图片描述


//测试排序的性能对⽐
void TestOP()
{srand(time(0));const int N = 100000;int* a1 = (int*)malloc(sizeof(int) * N);int* a2 = (int*)malloc(sizeof(int) * N);int* a3 = (int*)malloc(sizeof(int) * N);int* a4 = (int*)malloc(sizeof(int) * N);int* a5 = (int*)malloc(sizeof(int) * N);int* a6 = (int*)malloc(sizeof(int) * N);int* a7 = (int*)malloc(sizeof(int) * N);for (int i = 0; i < N; ++i){a1[i] = rand();a2[i] = a1[i];a3[i] = a1[i];a4[i] = a1[i];a5[i] = a1[i];a6[i] = a1[i];a7[i] = a1[i];}int begin1 = clock();InsertSort(a1, N);int end1 = clock();int begin2 = clock();ShellSort(a2, N);int end2 = clock();int begin3 = clock();SelectSort(a3, N);int end3 = clock();int begin4 = clock();HeapSort(a4, N);int end4 = clock();int begin5 = clock();QuickSort(a5, 0, N - 1);int end5 = clock();int begin6 = clock();MergeSort(a6, N);int end6 = clock();int begin7 = clock();BubbleSort(a7, N);int end7 = clock();printf("InsertSort:%d\n", end1 - begin1);printf("ShellSort:%d\n", end2 - begin2);printf("SelectSort:%d\n", end3 - begin3);printf("HeapSort:%d\n", end4 - begin4);printf("QuickSort:%d\n", end5 - begin5);printf("MergeSort:%d\n", end6 - begin6);printf("BubbleSort:%d\n", end7 - begin7);free(a1);free(a2);free(a3);free(a4);free(a5);free(a6);free(a7);
}

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

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

相关文章

【安全通信】告别信息泄露:搭建你的开源视频聊天系统briefing

文章目录 前言1.关于briefing2.本地部署briefing3.使用briefing4.cpolar内网穿透工具安装5.创建远程连接公网地址6.固定briefing公网地址 前言 在这个信息爆炸的时代&#xff0c;视频聊天几乎成了我们日常沟通的标配。但你是否曾在视频会议中感到不安&#xff0c;担心自己的私…

RTOS基础-信号量和队列

引言 消息队列用于传输多个数据&#xff0c;但是有时候我们只需要传递状态&#xff0c;这个状态值需要用一个数值表示&#xff0c;使用信号量效率更高、更节省内存 信号&#xff1a;起通知作用 量&#xff1a;还可以用来表示资源的数量 当"量"没有限制时&#x…

pip install tkinter报错

pip install tkinter&#xff1a;ERROR: Could not find a version that satisfies the requirement tkinter 这是因为&#xff0c;安装python的时候没有安装tkinter选项&#xff0c;解决这个问题有下面两种方法 一、重新安装python 但是这个步骤有点麻烦 二、在python-3.1…

Java 实现自定义 LRU 缓存

一、引言 在现代软件系统中&#xff0c;缓存是提高性能的重要手段之一。LRU 缓存作为一种常用的缓存策略&#xff0c;能够根据数据的使用频率自动淘汰最近最少使用的数据&#xff0c;从而保持缓存的高效性。在 Java 中&#xff0c;虽然有一些现成的缓存框架可供使用&#xff0c…

Python的面向对象day7

1、什么是面向对象 面向对象称为OO&#xff0c;他通过将数据和功能封装在一个被称为‘对象’的实体中&#xff0c;来组织和管理代码。面向对象变成&#xff08;OOP&#xff09;具有四个特性&#xff0c;封装、继承、多态、抽象 优点&#xff1a;模块化、安全性高、代码重用性…

自动化工具 Gulp

自动化工具 gulp 摘要 概念&#xff1a;gulp用于自动化开发流程。 理解&#xff1a;我们只需要编写任务&#xff0c;然后gulp帮我们执行 核心概念&#xff1a; 任务&#xff1a;通过定义不同的任务来组织你的构建流程。 管道&#xff1a;通过管道方式将文件从一个插件传递…

大华Android面试题及参考答案

请解释 Service 和 IntentService 之间的区别。 Service 是 Android 中的一种组件,用于在后台执行长时间运行的操作,不提供用户界面。它可以通过 startService () 或者 bindService () 方法来启动。当通过 startService () 启动时,服务会一直运行直到自己停止或者被系统回收…

探索 Seata 分布式事务

Seata(Simple Extensible Autonomous Transaction Architecture)是阿里巴巴开源的一款分布式事务解决方案,旨在帮助开发者解决微服务架构下的分布式事务问题。它提供了高效且易于使用的分布式事务管理能力,支持多种事务模式,确保数据的一致性和完整性。 以下是 Seata 的一…

【QT常用技术讲解】优化网络链接不上导致qt、qml界面卡顿的问题

前言 qt、qml项目经常会涉及访问MySQL数据库、网络服务器&#xff0c;并且界面打开时的初始化过程就会涉及到链接Mysql、网络服务器获取数据&#xff0c;如果网络不通&#xff0c;卡个几十秒&#xff0c;会让用户觉得非常的不爽&#xff0c;本文从技术调研的角度讲解解决此类问…

探索美赛:从准备到挑战的详细指南

前言 美国大学生数学建模竞赛&#xff08;MCM/ICM&#xff09;&#xff0c;简称“美赛”&#xff0c;是全球规模最大的数学建模竞赛之一。它鼓励参赛者通过数学建模来解决现实世界中的复杂问题&#xff0c;广受世界各地大学生的欢迎。本文将详细介绍美赛的全过程&#xff0c;从…

selenium 控制内嵌table滚动条的方法

selenium 控制内嵌table滚动条的方法 我们经常会遇到selenium 无法捕获到对应元素的问题&#xff0c;其中有一个原因是由于页面中存在滚动条&#xff0c;而需要操作的元素需要滑动滚动条后才能捕获到。 之前有使用过如下方式&#xff1a; document.getElementById(id).scrollT…

编程之路,从0开始:知识补充篇

Hello大家好&#xff0c;很高兴我们又见面了&#xff01; 给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 这一篇我们来补充一下在之前篇目没讲到的知识&#xff0c;并结合一些码友的私信提问和我在编程中遇到的问题&#xff0c;做一些易错点或易混点的讲解。 …

C语言中,让人又爱又恨的字符串编码

引言 在C语言的世界里&#xff0c;字符串编码是一个让人既爱又恨的话题。 所有的打印信息&#xff0c;都是以字符串输出的。但是&#xff0c;大家在编码的时候&#xff0c;经常会遇到一些情况&#xff0c;稍不注意&#xff0c;就会导致显示出乱码&#xff0c;到了客户那里&…

Javaweb—Ajax与jQuery请求

文章目录 十一.Javaweb—Ajax与jQuery请求11.1 异步/同步请求11.2 异步请求案例案例一&#xff1a;案例二&#xff1a; 十一.Javaweb—Ajax与jQuery请求 Ajax: 全称Asynchronous JavaScript And XML&#xff0c;异步的JavaScript和XML。 11.1 异步/同步请求 【往期文章】 同…

单片机中的BootLoader(重要的概念讲解)

文章目录 一、链接地址和执行地址1. 链接地址(Load Address)2. 执行地址(Execution Address)链接地址与执行地址的关系实际工作流程总结二、相对跳转和绝对跳转1. 相对跳转(Relative Jump)2. 绝对跳转(Absolute Jump)3. `BX` 和 `BL` 指令总结三、散列文件1. 散列文件的…

macOS解决U盘装完系统容量变小的问题

发现原来256GB容量的U盘在mac电脑上只显示34GB&#xff0c;想起来之前用该U盘装过系统&#xff0c;最终搜到了以下解决方案&#xff0c;在此记录&#xff1a; (1) 查看盘符列表&#xff0c;找到需要格式化的U盘&#xff0c;假设为disk4 diskutil list(2) 卸载分区disk4 disk…

Linux 系统管理和监控命令---- auditctl命令

文章目录 基本语法常用参数和选项添加规则删除规则查看规则控制审计系统其他选项 使用示例启用审计系统禁用审计系统添加文件监视规则删除文件监视规则添加系统调用规则删除系统调用规则列出当前的审计规则 结合 ausearch 和 aureport查询审计日志生成审计报告 总结 auditctl 是…

知识图谱6:neo4j查询语句

neo4j增删改查 常见查询语句 1、查询所有节点和关系 //查询所有节点和关系 MATCH (n)-[r]->(m) RETURN n, r, m 2、查询某个知识图谱的全部 3、查询 MATCH (n:zhongyao {name: "艾虎"})-[r]->(m) RETURN n, r, m4、统计 // 查询边的个数 MATCH ()-[r]->…

【计算机网络】UDP网络程序

一、服务端 1.udpServer.hpp 此文件负责实现一个udp服务器 #pragma once#include <iostream> #include <string> #include <cstdlib> #include <cstring> #include <functional> #include <strings.h> #include <unistd.h> #incl…

【027B】基于51单片机模拟电梯(点阵)【Proteus仿真+Keil程序+报告+原理图】

☆、设计硬件组成&#xff1a;51单片机最小系统8*8点阵显示按键设置LED灯。 1、设计采用STC89C51/52、AT89C51/52、AT89S51/52作为主控芯片&#xff1b; 2、采用8*8点阵显示楼层和电梯运作&#xff08;上升、下降&#xff09;指示&#xff0c;同时具有八个楼层指示灯&#xf…