归并排序和分治

归并排序

归并排序是利用归并的思想实现的排序方法,该算法采用经典的分治策略(分治法将问题成一些小的问题然后递归求解,而的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。

分而治之

可以看到这种结构很像一棵完全二叉树,本文的归并排序我们采用递归去实现(也可采用迭代的方式去实现)。

过程:左部分排好序,右部分排好序,利用merge过程让左右整体有序(merge过程:谁小拷贝谁,直到左右两部分所有的数字耗尽)

归并排序算法有两个基本的操作,一个是,也就是把原数组划分成两个子数组的过程。另一个是,它将两个有序数组合并成一个更大的有序数组。

  1. 将待排序的线性表不断地切分成若干个子表,直到每个子表只包含一个元素,这时,可以认为只包含一个元素的子表是有序表。
  2. 将子表两两合并,每合并一次,就会产生一个新的且更长的有序表,重复这一步骤,直到最后只剩下一个子表,这个子表就是排好序的线性表。

阶段

可以理解为就是递归拆分子序列的过程,利用二分法

递归深度为log2n。

合并两个有序数组流程

再来看看阶段,我们需要将两个已经有序的子序列合并成一个有序序列,比如上图中的最后一次合并,要将[4,5,7,8]和[1,2,3,6]两个已经有序的子序列,合并为最终序列[1,2,3,4,5,6,7,8],来看下实现步骤。

代码:

# include <stdio.h>int arr[100];
inr help[100];int n;void mergesort(int l, int r)
{if (l == r)return;int m = (l+r) / 2;mergesort(l, m);mergesort(m+1, r);merge(l, m, r); //让左右整体有序 
}//让 l 到 r 变 有序
//把[l, m] 和 [m+1, r]进行合并 
void merge(int l, int m, int r)
{int i = l;int a = l;int b = m+1; while (a <= m && b <=r){if (arr[a] <= arr[b]){help[i] = arr[a];a = a + 1;}else{help[i] = arr[b];b = b + 1;}i = i + 1;}//左侧指针,右侧指针,必有一个越界,另一个不越界while (a <= m){help[i] = a;i = i + 1;a = a + 1;} while (b <= r){help[i] = b;i = i + 1;b = b + 1;} 	for (int i=l; i<=r; ++i){arr[i] = help[i];}
}int main()
{scanf("%d", &n);for (int i=0; i<n; ++i)scanf("%d", &arr[i]);mergesort(0, n-1);}

归并分治



问题一

本题发现

符合第一个原理

在计算跨越左右产生的答案时,我们发现如果左、右各有序,则会提高计算便利性

因此就可以考虑归并分治

代码:

# include <stdio.h>int arr[100];
int help[100];int n;int sum(int l, int r)
{if (l == r)return 0;int m = (l + r) / 2;return sum(l, m) + sum(m+1, r) + merge(l, m, r);
}int merge(int l, int m, int r)
{int ans = 0;int j = l;int sum = 0;for (int i=m+1; i<r; ++i){while (j <= m && arr[i] >= arr[j]){sum = sum + arr[j];j = j + 1;}ans = ans + sum;}int i = l;int a = l;int b = m + 1;while (a <= m && b <=r){if (arr[a] <= arr[b]){help[i] = arr[a];a = a + 1;}else{help[i] = arr[b];b = b + 1;}i = i + 1;}//左侧指针,右侧指针,必有一个越界,另一个不越界while (a <= m){help[i] = a;i = i + 1;a = a + 1;} while (b <= r){help[i] = b;i = i + 1;b = b + 1;} 	for (int i=l; i<=r; ++i){arr[i] = help[i];}
}int main()
{scanf("%d", &n);for (int i=0; i<n; ++i)scanf("%d", &arr[i]);int ans = sum(0, n-1);}

问题二

符合第一个原理

在计算跨越左右产生的答案时,我们发现如果左、右各有序,则会提高计算便利性

因此就可以考虑归并分治

代码:

# include <stdio.h>int arr[100];
int help[100];int n;int cmp(int l, int r)
{if (l == r)return 0;int m = (l+r) / 2;return cmp(l, m) + cmp(m+1, r) + merge(l, m, r);
}int merge(int l, int m, int r)
{int j = l;int q = m+1;int sum = 0;int ans = 0;for (int i=l; i<=m; ++i){while (q <= r && arr[i] > arr[q] * 2){q = q + 1;}ans = ans + (q - m - 1) - i;}int x = l;int a = l;int b = m + 1;while (a <= m && b <=r){if (arr[a] <= arr[b]){help[x] = arr[a];a = a + 1;}else{help[x] = arr[b];b = b + 1;}x = x + 1;}//左侧指针,右侧指针,必有一个越界,另一个不越界while (a <= m){help[x] = a;x = x + 1;a = a + 1;} while (b <= r){help[x] = b;x = x + 1;b = b + 1;} 	for (int i=l; i<=r; ++i){arr[i] = help[i];}return ans;
}int main()
{scanf("%d", &n);for (int i=0; i<n; ++i)scanf("%d", &arr[i]);}

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

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

相关文章

Unity Mesh 生成图形(二)

一、概述 Unity 的 Mesh 是用于表示三维物体的网格数据结构。它是由一系列顶点和三角形组成的网格&#xff0c;用于描述物体的形状和外观。 Mesh 是由顶点、三角形和其他相关信息组成的&#xff0c;它用于在 Unity 中创建和渲染三维对象。顶点是网格的基本构建单元&#xff0…

Linux 设备树: 设备树节点与属性在 dtb 文件中的存储

前言 当前新版本的 Linux 内核 设备驱动框架&#xff0c;与设备树&#xff08;Device Tree&#xff09;结合密切&#xff0c;整体 设备树的设备驱动框架&#xff0c;比较的庞大&#xff0c;但又非常的经典。 一个个的 设备树解析函数&#xff0c;都是前人【智慧】的结晶&#…

go: go.mod file not found in current directory or any parent directory.如何解决?

这个错误表明你正在执行 go get 命令&#xff0c;但是当前目录或任何父目录中都找不到 go.mod 文件。这可能是因为你的项目还没有使用 Go Modules 进行管理。 要解决这个问题&#xff0c;有几种方法&#xff1a; go mod init <module-name> 其中 <module-name>…

华为OD机试 - 最大社交距离(Java 2024 C卷 100分)

华为OD机试 2024C卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷C卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;每一题都有详细的答题思路、详细的代码注释、样例测试…

基于 java + Springboot + vue +mysql 大学生实习管理系统(含源码)

目录 &#x1f4da; 前言 &#x1f4d1;摘要 &#x1f4d1;实习管理系统的特点 &#x1f4d1;使用架构 &#x1f4da; 总体设计 &#x1f4da; 数据库设计 &#x1f4ac; 系统公告实体属性 &#x1f4ac; 单位成绩实体属性 &#x1f4ac; 学生实体属性 &#x1f4da; 系…

超市销售数据-python数据分析项目

Python数据分析项目-基于Python的销售数据分析项目 文章目录 Python数据分析项目-基于Python的销售数据分析项目项目介绍数据分析结果导出数据查阅 数据分析内容哪些类别比较畅销?哪些商品比较畅销?不同门店的销售额占比哪个时间段是超市的客流高封期?查看源数据类型计算本月…

10.图像高斯滤波的原理与FPGA实现思路

1.概念 高斯分布 图像滤波之高斯滤波介绍 图像处理算法|高斯滤波   高斯滤波(Gaussian filter)包含很多种&#xff0c;包括低通、高通、带通等&#xff0c;在图像上说的高斯滤波通常是指的高斯模糊(Gaussian Blur)&#xff0c;是一种高斯低通滤波。通常这个算法也可以用来模…

02 - 全加器和加法器

---- 整理自B站UP主 踌躇月光 的视频 1. 全加器 用门电路实现两个二进制数相加并求出和的组合线路&#xff0c;称为一位全加器。一位全加器可以处理低位进位&#xff0c;并输出本位加法进位。全加器比半加器多了一位进位。 1.1 实验 1&#xff1a;通过两个半加器设计全加器 1.…

【游戏漏洞】逆向基础之进制

本文给大家讲解我们日后逆向学习和实践过程中息息相关的一些重要基础 我们要讲解的是 例如 111在什么时候是正确的&#xff1f; OD&#xff0c;CE&#xff0c;IDA等工具为什么都是16进制&#xff1f; 计算机只认识0和1&#xff0c;也就2进制。 我们现实生活中常用到的是10进…

【LeetCode热题100】79. 单词搜索(回溯)

一.题目要求 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其中“相邻”单元格是那些水平…

Vue3+Vite Nginx部署 跨域

打包项目 webstorm打开项目之后&#xff0c;在Terminal执行打包命令 pnpm run build:prod 复制到Nginx 打包完成之后,生成的包在根目录dist&#xff0c;把dist目录拷贝到Nginx放网站目录下&#xff1a;\nginx-1.25.2\html\divided &#xff0c;dist改名了divided 修改配置…

Runes 生态一周要览 ▣ 2024.3.25-3.31|Runes 协议更新 BTC 减半在即

Runes 生态大事摘要 1、Casey 发布了 Runes 协议文档 RUNES HAVE DOCS&#xff0c;Github 代码库更新到 ord 0.17.0 版本&#xff0c;Casey 表示符文是一个“严肃”的代币协议。 2、Casey 公布了第一个硬编码的创世符文「UNCOMMONGOODS」 3、4月7日香港沙龙&#xff5c;聚焦「…