博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++ 归并排序 个人笔记
阅读量:3966 次
发布时间:2019-05-24

本文共 2687 字,大约阅读时间需要 8 分钟。

C++ 归并排序 个人笔记

一.归并排序的基本思想

一个数组分成先以中间为界,把其均分为 A 和 B 两个数组(如果是奇数个,允许两组数相差一个),这二组数据必须是有序的,我们可以依次从两组中取最前面的那个最小元素依次有序放到临时的数组中,然后再把临时数组中有序的数据拷贝到原数组中,快速完成排序(归并法)

但是一个待排序的数组从中间分成二组数据,不可能二组数据都是有序的,我可以用分治的手法,把数组分到只有二个数据然后进行归并法

二. 归并排序的代码实现

建议从main()函数开始看代码

源代码

#include 
using namespace std;/****************************** 函数前提: 将一组数据分成二组 这两组的数据都是从小到大有序的 (如果是奇数个,允许两组数据相差一个)* 函数作用: 利用一个临时数组将一个数组排序一个数组中一个区间的数据排序* * 函数参数: arr - 需要排序的数组的首地址;* left - 左边组开始的数组下标* middie - 右边组开始的数组下标 * 也是左边组结束数组下标的下一个下标* right - 右边组结束的数组下标 * 这个区间最后一个数组下标* tmp - 临时保存已排好序的数组* * 函数返回值: 无****************************/void mergerAdd(int* arr, int left, int middie, int right,int* tmp) { if (!arr || !tmp) return; int size = left; //临时数组的下标 int i = left; //i指向左边组开始的数组下标, int j = middie;//j指向右边组开始的数组下标, while (i < middie && j <= right) { //因为这两组是有序的 //比如 左边组 1 3 5 //右边数据 2,4,6 //从第一个元素比较 1比2小 1进入临时数组 //i++ 下标指向 3 //循环直到一组数据完成遍历循环结束 if (arr[i] > arr[j]) { tmp[size++] = arr[j]; j++; } else { tmp[size++] = arr[i]; i++; } } //左边的数据没有完成遍历 while (i < middie) { //肯定是最大的数 依次进入临时数组 tmp[size++] = arr[i]; i++; } //右边的数据没有完成遍历 while (j <= right) { tmp[size++] = arr[j]; j++; } //当前tmp数组是一个有序数组 /* ************************************** *函数作用: 内存拷贝 *函数参数: 第一个参数是需要拷贝到的目的地(地址) * 第二个参数是待拷贝的地址 * 第三个参数是需要拷贝的字节数 * ******************************* */ //为什么第一个参数是arr+ left? //比如传入的是参数是: arr数组:7,2,4,1,3,7, left = 1,middie = 2,right = 4 //下标为0 的数据不变 从下标为1到下标为4这个区间的数据 //分为二组开始合并成一个有序数组保存在tmp 临时数组中 //如果从arr的首地址开始进行数据拷贝会导致在这个区间以外的数据发生被覆盖 memcpy(arr + left, tmp + left, sizeof(int) * (right - left + 1));}/*************************************函数作用: 归并排序**函数参数: arr - 需要排序的数组* left - 从这个位置开始排序的数组下标* right - 结束的数组下标 left 到 right 是需要排序的区间* tmp - 临时保存已排好序的数组* * 函数返回值 : 无*/void mergerSort(int* arr, int left, int right, int* temp) { int middie = -1; //这个条件使得这个指定区间能一分为二 //分到这区间只有2个数据 if (left < right) { //middie取left和right相对中间的下标 middie = (right - left) / 2 + left; //middie 左边的数据进行排序(包括middie) mergerSort(arr, left, middie, temp); //middie+1 右边的数据进行排序 mergerSort(arr, middie + 1, right, temp); //这个区间只有2个数据后分成二组 这二组都是有序的 //一组一个数据进行合并 //这个区间成为一个有序数组 mergerAdd(arr, left, middie+1, right,temp); }}int main(void) { int test[] = { 1,14,11,10,23,15,21,13,25}; int len = sizeof(test) / sizeof(test[0]); int* tmp = new int[len]; //int middie = len / 2; mergerSort(test, 0, len-1,tmp); for (int i = 0; i < len; i++) { printf("%d\t", test[i]); } delete[] tmp; return 0;}

代码测试

在这里插入图片描述

三.归并排序的递归过程

红线-左边数组分治也就是归并排序中第一次调用的函数

蓝线-右边数组分治也就是归并排序中第二次调用的函数

因为数组的个数越多,调用函数的次数越多,调用过程是重复的,我选了4个数来进行归并排序

在这里插入图片描述

转载地址:http://kbyki.baihongyu.com/

你可能感兴趣的文章
NET - .NET Core 之 Abp AuditLog 将不同的Controller实体的审计日志存储到不同的Table
查看>>
NET - .NET Core 之 Azure Key Vault 密钥保管库的使用
查看>>
NET - .NET Core 之 Abp 整合 Quartz
查看>>
Docker - Docker Desktop(WSL2)修改镜像存储位置
查看>>
NET - NET Core使用Log4net的SqlServer AdoNetAppender 报程序集错误
查看>>
NET - NET Core中使用Log4net输出日志到数据库中去
查看>>
NET - NET Core 迁移nuget包缓存到指定位置
查看>>
Spring - SpringBoot 集成 swagger2
查看>>
SQL - 深入理解MySQL索引之B+Tree
查看>>
SQL - 数据库索引原理,及MySQL索引类型
查看>>
Spring - Dubbo的实现原理
查看>>
Spring - Dubbo 扩展点详解
查看>>
Spring - Hystrix原理与实战
查看>>
Spring - Sentinel 原理 全解析
查看>>
Spring - 比较Sentinel和Hystrix
查看>>
Spring - Nacos 服务注册与发现原理分析
查看>>
Spring - Nacos 配置中心原理分析
查看>>
Spring - Nacos 配置实时更新原理分析
查看>>
Android开发MVP模式(解决了View和Model的耦合)
查看>>
Android网络框架Volley(实战篇)
查看>>