[数据结构]———归并排序

2024-05-04 01:04
文章标签 数据结构 归并 排序

本文主要是介绍[数据结构]———归并排序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

具体代码:在gitee仓库:登录 - Gitee.com

目录

​编辑

1.基本思想:

 

2. 代码解析

1.分析

 2.逻辑图

3.运行结果 


1.基本思想:


归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide andConquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。 归并排序核心步骤:

2. 代码解析

1.分析

归并排序的逻辑过程可以通过几个关键步骤来可视化:

  1. 分解: 数组最初被分成两个子数组,这个过程递归进行,直到每个子数组只有一个元素。
  2. 合并: 递归结束后,开始合并过程,将相邻的两个有序子数组比较元素大小,较小的元素会被先放到临时数组中。
  3. 完整排序: 通过不断合并子数组,最终得到完全排序的数组
  1. _MergeSort 函数 是递归函数,负责实际的排序工作。

    • 输入参数a 是待排序的数组指针,begin 和 end 分别表示当前子数组的起始和结束下标,tmp 是一个临时数组用于辅助合并两个已排序的子数组。
    • 当 begin >= end 时,说明当前子数组只剩一个元素或为空,无需排序,直接返回。
    • 计算中间点 mid,对左右两半 [begin, mid] 和 [mid+1, end] 分别递归调用 _MergeSort 进行排序。
    • 调用结束后,通过比较并合并两个有序子数组 [begin, mid] 和 [mid+1, end] 到临时数组 tmp 中。
    • 最后,将排好序的 tmp 数组复制回原数组 a 的相应位置。
  2. MergeSort 函数 是主接口函数,负责初始化和释放临时数组。

    • 动态分配与原数组相同大小的临时数组 tmp
    • 调用 _MergeSort 函数进行排序。
    • 使用完毕后,释放临时数组 tmp 的内存。

 2.逻辑图

void _MergeSort(int* a, int begin, int end, int* tmp)
{//划分
if (begin >= end)//只有一个元素不用划分return;int mid = (begin + end) / 2;//首尾下标相加除2得到中间点下标_MergeSort(a, begin, mid, tmp);//递归划分左半区域_MergeSort(a, mid + 1, end, tmp);//递归划分右半区域// [begin, mid][mid+1, end]归并int begin1 = begin, end1 = mid;//标记左半区第一个未排序的元素以及最后一个元素int begin2 = mid + 1, end2 = end;//标记右半区第一个未排序的元素以及最后一个元素int i = begin;//临时数组下标while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2])//左半区第一个未排序的元素小于右半区第一个未排序的元素{tmp[i++] = a[begin1++];}else{tmp[i++] = a[begin2++];//右半区第一个未排序的元素小于左半区第一个未排序的元素}}//合并左半区剩余元素while (begin1 <= end1){tmp[i++] = a[begin1++];}
//合并右半区剩余元素while (begin2 <= end2){tmp[i++] = a[begin2++];}
//把临时数组中合并后的元素拷贝回原数组memcpy(a + begin, tmp + begin, sizeof(int) * (end - begin + 1));
}//归并排序入口
void MergeSort(int* a, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);//开辟一个辅助数组if (tmp == NULL){perror("malloc fail");return;}_MergeSort(a, 0, n - 1, tmp);free(tmp);
}

3.运行结果 

这篇关于[数据结构]———归并排序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/958031

相关文章

iOS 数组排序

##1、字母排序 NSArray *arrData = @[@"i",@"b",@"a",@"d",@"e",@"f",@"g",@"h",@"c"];NSArray *sortArray = [arrData sortedArrayUsingSelector:@selector(compare:)];NSLog(@"%@",sortArray); 输出结果: ##2、数字排序

【深入理解MySQL的索引数据结构】

文章目录 📕索引底层数据结构与算法📙索引数据结构📘二叉树📘红黑树📘Hash📘B-Tree📘B+Tree 📙表在不同存储引擎的存储结构📘MyISAM存储引擎索引实现📚文件结构📚非聚集索引 📘InnoDB存储引擎索引实现📚文件结构📚聚集索引 📙为什么DBA总推荐使用整型自增主键做索引📙为什么非主键索引结构叶子节点存储的是主键值?📙MySQL最左前缀优化原则是怎

Lintcode 合并两个排序的链表

将两个排序链表合并为一个新的排序链表 样例 给出 1->3->8->11->15->null,2->null, 返回 1->2->3->8->11->15->null。 递归实现: """Definition of ListNodeclass ListNode(object):def __init__(self, val, next=None):self.val = valself.n

【算法】二分查找——在排序数组中查找元素的第一个和最后一个位置

本节博客主要是通过“在排序数组中查找元素的第一个和最后一个位置”总结关于二分算法的左右界代码模板,有需要借鉴即可。 目录 1.题目2.二分边界算法2.1查找区间左端点2.1.1循环条件2.1.2求中点的操作2.1.3总结 2.2查找区间右端点2.1.1循环条件2.1.2求中点的操作2.1.3总结 2.3总结 3.参考解题代码4.模板总结5.总结 1.题目 题目链接:LIN

【董晓算法】竞赛常用知识点之数据结构1

前言: 本系列是学习了董晓老师所讲的知识点做的笔记 董晓算法的个人空间-董晓算法个人主页-哔哩哔哩视频 (bilibili.com)  动态规划系列(还没学完) 【董晓算法】动态规划之线性DP问题-CSDN博客 【董晓算法】动态规划之背包DP问题(2024.5.11)-CSDN博客 【董晓算法】动态规划之背包DP与树形DP-CSDN博客 字符串系列 【董晓算法】竞赛常用知识之字符

【高阶数据结构(四)】图的最短路径问题

💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:高阶数据结构专栏⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习更多数据结构   🔝🔝 高阶数据结构 1. 前言2. 单源最短路径问题3. dijkstra算法讲解4. bellman-Ford算法讲解5. 多源最短路径问题6. Floyd-Warshall算法讲解7. 总结

对于集合中的自定义对象使用collections.sort 进行排序,需要实现compartor接口

/**  * 榜单 业务类  *  * @author seawind  *  */ public class RankService {     // 查看榜单     public List<Orderitem> showRank() {         RankDAO rankDAO = new RankDAO();         List<O

数据结构——软考探究(一)

继上篇博客之后,对软考涉及的知识有了更深入的研究,本篇博客将会和大家分享对于数据结构的学习。数据结构是软考中比较重要的一块知识,它介绍了计算机中数据的内部构成,即一个数据由那些成分数据构成,以什么方式构成,呈什么结构。对于我们对于计算机知识的深入研究有很好的帮助,同时以此为基础也会很好地帮助我们去挖掘计算机的潜能,实现各方面性能的最优化。 对于数据结构的知识,自己总结了以下的框图:

【数据结构】排序(直接插入排序,希尔排序)

目录 一、排序的概念  二、常见的排序算法  三、插入排序 1.直接插入排序  1.直接插入排序实现 2.直接插入排序特性及复杂度 2.希尔排序  1.排序思路 2.希尔排序实现  3.希尔排序的特性及复杂度  一、排序的概念 排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。 稳定性:假定在待排序的记录序列中,存在

排序之单链表插入排序

//插入排序LinkList* LinkList::Sorting(){LinkNode *p1 = phead->pnext;//前指针LinkNode *p2 = p1->pnext;//当前指针LinkNode *p=phead->pnext;//滚动指针LinkNode *pp=phead;//滚动指针的前一个指针 LinkNode *q=phead->pnext;//始终指向第一个有