2024年最新归并排序算法C++实现(超详细解析!!,2024年最新再不刷题就晚了

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

将排好序的有序子序列进行合并,得到最终的有序序列。

3.算法分析

首先我们先给定一个无序的数列(42,15,20,6,8,38,50,12),我们进行合并排序数列,如下图流程图所示:

步骤一:首先将待排序的元素分成大小大致相同的两个序列。

步骤二:再把子序列分成大小大致相同的两个子序列。

步骤三:如此下去,直到分解成一个元素停止,这时含有一个元素的子序列都是有序的。

步骤四:进行合并操作,将两个有序的子序列合并为一个有序序列,如此下去,直到所有的元素都合并为一个有序序列。

举例,下面我将以序列(4,9,15,24,30,2,6,18,20)进行图解。

(1)初始化:i = low,j = mid+1,mid = (low+hight)/2 ,申请一个辅助数组 b

int* b = new int[hight - low + 1];  //用 new 申请一个辅助函数
	int i = low, j = mid + 1, k = 0;    // k为 b 数组的小标

(2)现在比较 a [i]  和 b[j]  ,将较小的元素放在 b 数组中,相应的指针向后移动,直到 i > mid 或者 j>hight 时结束。

while (i <= mid && j <= hight)  
 {
	if (a[i] <= a[j])
	{
		b[k++] = a[i++];  //按从小到大存放在 b 数组里面
	}
	else
	{
		b[k++] = a[j++];
	}
  }

进行第一次比较 a[i]=4  和 a[j]=2,将较小的元素 2 放入数组  b  中,j++,k++,如下图:

进行第二次比较 a[i]=4  和 a[j]=6,将较小的元素放 4 入数组  b  中,i++,k++,如下图:

进行第三次比较 a[i]=9  和 a[j]=6,将较小的元素放 6 入数组  b  中,j++,k++,如下图:

进行第四次比较 a[i]=9  和 a[j]=18,将较小的元素放 9 入数组  b  中,i++,k++,如下图:

 进行第五次比较 a[i]=15  和 a[j]=18,将较小的元素放 15 入数组  b  中,i++,k++,如下图:

进行第六次比较 a[i]=24  和 a[j]=18,将较小的元素放 18 入数组  b  中,j++,k++,如下图:

进行第七次比较 a[i]=24  和 a[j]=20,将较小的元素放 20 入数组  b  中,j++,k++,如下图:

 此时,j>hight 了,while循环结束,但 a 数组还剩下元素(i<mid)可直接放入  b  数组就可以了。如下图所示:

while (i <= mid)  // j 序列结束,将剩余的 i 序列补充在 b 数组中 
	{
		b[k++] = a[i++];
	}
	while (j <= hight)// i 序列结束,将剩余的 j 序列补充在 b 数组中 
	{
		b[k++] = a[j++];
	}

现在将  b  数组的元素赋值给 a 数组,再将 b  数组销毁,即可。

for (int i = low; i <= hight; i++)  //将 b 数组的值传递给数组 a
	{
		a[i] = b[k++];
	}
	delete[]b;     // 辅助数组用完后,将其的空间进行释放(销毁)

(3)递归的形式进行归并排序

void mergesort(int* a, int low, int hight) //归并排序
{
	if (low < hight)
	{
		int mid = (low + hight) / 2;
		mergesort(a, low, mid);          //对 a[low,mid]进行排序
		mergesort(a, mid + 1, hight);    //对 a[mid+1,hight]进行排序
		merge(a, low, mid, hight);       //进行合并操作
	}
}

三、AC代码

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
void merge(int* a, int low, int mid, int hight)  //合并函数
{
	int* b = new int[hight - low + 1];  //用 new 申请一个辅助函数
	int i = low, j = mid + 1, k = 0;    // k为 b 数组的小标
	while (i <= mid && j <= hight)  
	{
		if (a[i] <= a[j])
		{
			b[k++] = a[i++];  //按从小到大存放在 b 数组里面
		}
		else
		{
			b[k++] = a[j++];
		}
	}
	while (i <= mid)  // j 序列结束,将剩余的 i 序列补充在 b 数组中 
	{
		b[k++] = a[i++];
	}
	while (j <= hight)// i 序列结束,将剩余的 j 序列补充在 b 数组中 
	{
		b[k++] = a[j++];
	}
	k = 0;  //从小标为 0 开始传送
	for (int i = low; i <= hight; i++)  //将 b 数组的值传递给数组 a
	{
		a[i] = b[k++];
	}
	delete[]b;     // 辅助数组用完后,将其的空间进行释放(销毁)
}
void mergesort(int* a, int low, int hight) //归并排序
{
	if (low < hight)
	{
		int mid = (low + hight) / 2;
		mergesort(a, low, mid);          //对 a[low,mid]进行排序
		mergesort(a, mid + 1, hight);    //对 a[mid+1,hight]进行排序
		merge(a, low, mid, hight);       //进行合并操作
	}
}
int main()
{
	int n, a[100];
	cout << "请输入数列中的元素个数 n 为:" << endl;
	cin >> n;
	cout << "请依次输入数列中的元素:" << endl;
	for (int i = 0; i < n; i++)
	{
		cin >> a[i];
	}
	mergesort(a, 0, n-1);
	cout << "归并排序结果" << endl;
	for (int i = 0; i < n; i++)
	{
		cout << a[i] << " ";


![img](https://img-blog.csdnimg.cn/img_convert/2cfc18138f1a761dcd3c8ee05e6c54cc.png)
![img](https://img-blog.csdnimg.cn/img_convert/996db6a642cb51a74911c4edcb6ad17f.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**

15670978022)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值