C语言归并排序(合并排序)算法以及代码

合并排序是采用分治法,先将无序序列划分为有序子序列,再将有序子序列合并成一个有序序列的有效的排序算法。

原理:先将无序序列利用二分法划分为子序列,直至每个子序列只有一个元素(单元素序列必有序),然后再对有序子序列逐步(两两)进行合并排序。合并方法是循环的将两个有序子序列当前的首元素进行比较,较小的元素取出,置入合并序列的左边空置位,直至其中一个子序列的最后一个元素置入合并序列中。最后将另一个子序列的剩余元素按顺序逐个置入合并序列尾部即可完成排序。整体过程如下图:

 两个有序子序列合并的原理如下图:

代码:递归式实现

#include <malloc.h>
#include <stdlib.h>
void mergesort(int A[],int n)  //合并排序的递归主体
{void merge(int A[], int L[], int R[], int l, int r);  //声明merge函数if(n>1)    //多于一个元素才需要排序{int mid=n/2;int *left=(int*)malloc(sizeof(int)*mid);int *right=(int*)malloc(sizeof(int)*(n-mid));for(int i=0;i<mid;i++)left[i]=A[i];       //建立临时数组存储左半部分序列for(int j=mid;j<n;j++)right[j-mid]=A[j];  //建立临时数组存储右半部分序列mergesort(left,mid);    //调用自身对左半部分进行合并排序mergesort(right,n-mid); //调用自身对右半部分进行合并排序merge(A,left,right,mid,n-mid);   //两个有序序列的合并操作,封装为函数free(left);free(right);}
}void merge(int A[],int L[],int R[],int l,int r)  //两个有序序列L、R合并为A,l,r分别为L,R的长度
{int i=0,j=0,k=0;while(i<l&&j<r)  //两个子序列首元素做比较,小者取出置入父序列{if(L[i]<=R[j])A[k++]=L[i++];elseA[k++]=R[j++];}while(i<l)       //将左半部分剩余元素置入父序列{A[k++]=L[i++];}while(j<r)       //将右半部分剩余元素置入父序列{A[k++]=R[j++];}
}

改进:非递归式实现

递归式的实现方法,当输入规模增大时,会表现出效率低的缺点。且在排序过程中会不断的开辟临时空间,容易造成内存混乱。

void mergesort(int A[], int n){    //非递归实现。只开辟一个大小与待排序数组相同的存储数组,排序过程中直接在该数组上进行操作。不反复开辟临时数组int step;   int *p, *q, *t;int i, j, k, len1, len2;int *temp;  step = 1;      //初始步长为1,即将单个元素作为有序子序列进行合并p = A;q = (int*)malloc(sizeof(int)*n);  //q为临时开辟的空间,用来存储已排序序列,大小为待排序数组的长度temp = q;                              //temp与q指向同一段内存,留作最后释放内存空间时使用,因为q指针在后面排序操作中可能会改变指向while (step<n){i = 0;j = i + step;k = i;                             //k用作临时数组的下标len1 = i + step < n ? i + step : n;   //len1表示有序序列1的下标上限len2 = j + step < n ? j + step : n;   //len2表示有序序列2的下标上限while (i<n){while (i<len1&&j<len2)        //两个子序列首元素做比较,小者取出置入父序列{q[k++] = p[i]<p[j] ? p[i++] : p[j++];}while (i<len1)                //将子序列1的剩余元素置入父序列{q[k++] = p[i++];}while (j<len2)                //将子序列2的剩余元素置入父序列{q[k++] = p[j++];}i = j;                        //j经过自增变为len2,然后赋值给ij = i + step;                 //i被赋值为len2,加上步长再赋值给jk = i;                        len1 = i + step < n ? i + step : n;len2 = j + step < n ? j + step : n;}step *= 2;   //步长翻倍,即将原步长2倍个数的数组元素作为有序子序列进行合并t = p;       //t作为临时指针变量,用于交换p和q的指针指向p = q;       //将p指针指向经过一轮合并排序后的临时数组q = t;       //将q指针指向原数组}if (A != p){     //如果最终p指针的指向改变为临时数组,则将完成排序的数组拷贝至原数组memcpy(A, p, sizeof(int)*n);}free(temp);
}

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

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

相关文章

AtCoder Beginner Contest 333 A~F

A.Three Threes&#xff08;循环&#xff09; 题意&#xff1a; 给出一个正整数 N N N&#xff0c;要求输出 N N N个 N N N 分析&#xff1a; 按要求输出即可 代码&#xff1a; #include <bits/stdc.h> using namespace std;void solve() {int n;cin >> n;fo…

「遮天」段德互坑叶凡,期满至宝绿铜下落,老疯子限定回归

Hello,小伙伴们&#xff0c;我是拾荒君。 《遮天》第36集已经更新了&#xff0c;我迫不及待地跟随漫迷的脚步&#xff0c;前往观看。这一集中&#xff0c;叶凡在途中偶遇了一个醉酒的段德。这个段德之前曾沦陷在阴坟之中&#xff0c;如今能够逃出&#xff0c;可见他的实力深不…

ADC模拟/数字转换器

ADC是什么&#xff1f; 全称&#xff1a; Analog-to-Digital Converter &#xff0c;指模拟 / 数字转换器 它是一种电子设备或电路&#xff0c;用于将连续的模拟信号转换为相应的数字形式&#xff0c;以便于数字系统进行处理。模拟信号是连续变化的&#xff0c;而数字系统则处…

sensitive-word 敏感词之 DFA 双数组实现源码学习

拓展阅读 敏感词工具实现思路 DFA 算法讲解 敏感词库优化流程 java 如何实现开箱即用的敏感词控台服务&#xff1f; 各大平台连敏感词库都没有的吗&#xff1f; v0.10.0-脏词分类标签初步支持 v0.11.0-敏感词新特性&#xff1a;忽略无意义的字符&#xff0c;词标签字典 …

分享一个项目——Sambert UI 声音克隆

文章目录 前言一、运行ipynb二、数据标注三、训练四、生成总结 前言 原教程视频 项目链接 运行一个ipynb&#xff0c;就可操作 总共四步 1&#xff09;运行ipynb 2&#xff09;数据标注 3&#xff09;训练 4&#xff09;生成 一、运行ipynb 等运行完毕后&#xff0c;获得该…

全国1900+监测站点空气质量日数据,shp/excel格式,2023年最新数据

基本信息. 数据名称: 全国1900监测站点空气质量监测日数据 数据格式: shpexcel 时间版本&#xff1a;2023年 数据几何类型: 点 数据精度&#xff1a;全国 数据坐标系: WGS84 数据来源&#xff1a;网络公开数据 数据字段&#xff1a; 序号字段名称字段说明1province省…

echarts饼图点击区块事件

loadEchart: function (echartname, data) {option {title: {text: ,subtext: ,left: center},tooltip: {trigger: item,formatter: {c}%},legend: {orient: vertical,left: left,},series: [{name: ,type: pie,radius: 70%,data: [[name>合同额,value>12312312],],labe…

ros2机器人在gazebo中移动方案

原文连接Gazebo - Docs: Moving the robot (gazebosim.org) 很重要的地方&#xff1a;使用虚拟机运行Ubuntu的时候&#xff0c;需要关闭”加速3D图形“的那个选项&#xff0c;否则gazebo无法正常显示。 Moving the robot&#xff08;使用命令移动机器人示例&#xff09; In t…

SpringBoot知识点回顾01

Spring是为了解决企业级应用开发的复杂性而创建的&#xff0c;简化开发。 Spring是如何简化Java开发的 为了降低Java开发的复杂性&#xff0c;Spring采用了以下4种关键策略&#xff1a; 1、基于POJO的轻量级和最小侵入性编程&#xff0c;所有东西都是bean&#xff1b; 2、通…

《JVM由浅入深学习【一】 2023-12-19》JVM由简入深学习提升

JVM由浅入深一&#xff08;类加载&#xff09; JVM的类加载1. java运行时是什么时候被加载的&#xff1f;2. JVM类加载过程大致阶段3. 父类与子类初始化各个类型顺序4. 什么是类加载器&#xff1f;6. 双亲委派机制 JVM的类加载 1. java运行时是什么时候被加载的&#xff1f; …

TikTok获客工具开发,这些代码不能少!

随着TikTok的全球影响力不断扩大&#xff0c;越来越多的企业和个人开始将目光投向这个短视频平台。 为了在竞争激烈的市场中脱颖而出&#xff0c;开发一款高效的TikTok获客工具成为了迫切的需求&#xff0c;而在开发过程中&#xff0c;掌握一些基础源代码是必不可少的。 本文…

虾皮ERP系统:提升电商企业管理效率和水平的利器

虾皮ERP&#xff08;Enterprise Resource Planning&#xff0c;企业资源规划&#xff09;系统是电商企业管理业务流程和资源的重要工具。通过整合企业的各种功能模块&#xff0c;如采购、销售、库存和财务等&#xff0c;虾皮ERP系统实现了数据共享和流程自动化&#xff0c;从而…

数据结构学习 Leetcode300最长递增子序列

是我在学习动态规划时遇到的一道题。 题目&#xff1a; 一共有两种解法&#xff1a; 动态规划贪心 二分&#xff08;很难理解&#xff0c;我还没完全懂。。。&#xff09; 解法一&#xff1a;动态规划 思路&#xff1a; 状态&#xff1a;nums的前i个数的最长递增子序列。dp…

量子登月计划!Infleqtion与日本JST研发中性原子量子计算机

​&#xff08;图片来源&#xff1a;网络&#xff09; 美国量子信息公司Infleqtion&#xff0c;已被日本科学技术振兴机构&#xff08;JST&#xff09;选定为“量子登月计划”唯一的外国量子计算合作伙伴。该计划旨在增强日本的量子技术能力&#xff0c;预计将在2050年之前对日…

LDO的工作原理

LDO&#xff0c;全称是低压差线性稳压器。LDO使用的是在线性区域内运行的晶体管或者场效应管。通过调节晶体管或场效应管两端的电压&#xff0c;产生经过调整过的输出电压。 但仅能使用在降压应用中&#xff0c;也就是输出电压必须小于输入电压。 LDO内部基本都是由4大部件构成…

翻译: 负责任的人工智能 Responsible AI

负责任的人工智能指的是以道德、值得信赖和社会负责任的方式开发和使用人工智能。许多开发者、企业和政府都关心这一点&#xff0c;并且一直在进行对话&#xff0c;也在努力确保人工智能的构建和使用是负责任的。由于对负责任的人工智能的所有这些关注和努力&#xff0c;我们在…

苏州和数荣获苏州市软件行业协会“杰出贡献理事单位”

2023年12月14日&#xff0c;苏州市软件行业协会第五届第五次理事会议在金螳螂大厦顺利召开。 苏州市工信局副局长万资平&#xff0c;苏州市工信局大数据处处长卢剑荣&#xff0c;苏州市工信局大数据处丁天龙&#xff0c;江苏省软件行业协会副秘书长夏冰莹&#xff0c;苏州市软…

【SpringBoot快速入门】(2)SpringBoot的配置文件与配置方式详细讲解

之前我们已经学习的Spring、SpringMVC、Mabatis、Maven&#xff0c;详细讲解了Spring、SpringMVC、Mabatis整合SSM的方案和案例&#xff0c;上一节我们学习了SpringBoot的开发步骤、工程构建方法以及工程的快速启动&#xff0c;从这一节开始&#xff0c;我们开始学习SpringBoot…

SpringSecurity深度解析与实践(1)

目录 引言1. SpringSecurity1.1 SpringSecurity简介1.2 SpringSecurity工作原理1.3.特点 2. SpringSecurity的快速使用总结 引言 SpringSecurity作为Spring框架中的一个重要组成部分&#xff0c;扮演着保护应用程序安全的重要角色。本文将深入探讨SpringSecurity的原理、使用方…

logging模块

【 一 】前言 logging 模块是 Python 中用于记录日志信息的标准库模块。通过使用 logging 模块&#xff0c;你可以在应用程序中设置日志记录以追踪代码执行、错误报告等信息。 debug : 打印全部的日志( notset 等同于 debug )info : 打印 info, warning, error, critical 级别的…