当前位置: 首页 > 编程日记 > 正文

递归/分治:归并排序

前言

分治算法:
将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出 子问题的解后进行合并,就可得到原问题的解。

步骤如下:

  1. 分解,将要解决的问题划分成若 干规模较小的同类问题;
  2. 求解,当子问题划分得足够小时 ,用较简单的方法解决;
  3. 合并,按原问题的要求,将子问题 的解逐层合并构成原问题的解。
归并排序

在描述归并排序之前,我们先来看看如何合并两个有序数组,大概过程类似与之前描述过的两个有序链表的合并

实现过程如下:

void merge_two_arr(std::vector<int> &arr1, std::vector<int> &arr2, std::vector<int> &result) {int i = 0;int j = 0;/*在下标不断累加的过程中优先插入较小的一个元素,且对应的下标累加*/while(i < arr1.size() && j < arr2.size()) {if (arr1[i] <= arr2[j]) {result.push_back(arr1[i]);i++;} else {result.push_back(arr2[j]);j++;}}if (i == arr1.size()) { //将剩余的未合并的元素合入for (;j < arr2.size(); ++j) {result.push_back(arr2[j]);}} else {for (;i < arr1.size(); ++i) {result.push_back(arr1[i]);}}
}

依据分治算法的步骤,我们回到归并排序的过程上

以上过程即实现了分治算法的第三步:合并;

那么分治算法的第一步:分解,第二步:求解该如何做呢?

显然,我们的一个无序数组同样可以不断得二分,最终拆解为对底层的两两合并,对于每一个分解后的集合,我们同样使用合并有序数组(因为只有两个元素了,要做的就是对两个元素的合并)的过程。

实现如下:

void merge_sort(std::vector<int> &arr) {if (arr.size() < 2) {return ;}int mid = arr.size() / 2;std::vector<int> arr1;std::vector<int> arr2;for (int i = 0; i < mid; ++i) {arr1.push_back(arr[i]);}for (int i = mid; i< arr.size(); ++i){arr2.push_back(arr[i]);}merge_sort(arr1);merge_sort(arr2);arr.clear();/*以上递归返回的arr1和arr2为有序数组,最终合并两个有序数组即可*/merge_two_arr(arr1,arr2,arr); 
}

测试代码如下:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <stdlib.h>using namespace std;
/*合并两个有序数组*/
void merge_two_arr(std::vector<int> &arr1, std::vector<int> &arr2, std::vector<int> &result) {int i = 0;int j = 0;while(i < arr1.size() && j < arr2.size()) {if (arr1[i] <= arr2[j]) {result.push_back(arr1[i]);i++;} else {result.push_back(arr2[j]);j++;}}if (i == arr1.size()) {for (;j < arr2.size(); ++j) {result.push_back(arr2[j]);}} else {for (;i < arr1.size(); ++i) {result.push_back(arr1[i]);}}
}
/*归并排序*/
void merge_sort(std::vector<int> &arr) {if (arr.size() < 2) {return ;}int mid = arr.size() / 2;std::vector<int> arr1;std::vector<int> arr2;for (int i = 0; i < mid; ++i) {arr1.push_back(arr[i]);}for (int i = mid; i< arr.size(); ++i){arr2.push_back(arr[i]);}merge_sort(arr1);merge_sort(arr2);arr.clear();merge_two_arr(arr1,arr2,arr);
}int main(int argc, char const *argv[])
{std::vector<int> arr;int n; cin >> n;int tmp;for (int i = 0; i < n; ++i) {cin >> tmp;arr.push_back(tmp);}	merge_sort(arr);for (int i = 0;i < arr.size(); ++i) {cout << arr[i] << " ";}cout << endl;return 0;
}

输出如下:

#输入
5
-7 3 -4 -1 2
#输出
-7 -4 -1 2 3

相关文章:

Java中volatile 的使用场景有哪些?

volatile是一种轻量级的同步机制,它能保证共享变量的可见性,同时禁止重排序保证了操作的有序性,但是它无法保证原子性。所以使用volatilevolatile。

JDK22 正式发布了 !

Java 22 除了推出了新的增强功能和特性,也获得 Java Management Service (JMS) 的支持,这是一项新的 Oracle 云基础设施远程软件服务(Oracle Cloud Infrastructure, OCI) 原生服务,提供统一的控制台和仪表盘,帮助企业管理本地或云端的 Java 运行时和应用。使包含运行时计算值的字符串更容易表达,简化 Java 程序的开发工作,同时提高将用户提供的值编写成字符串,并将字符串传递给其他系统的程序的安全性。支持开发人员自由地表达构造器的行为。

Jackson 用起来!

你可以创建自定义序列化器和反序列化器以自定义特定字段或类的序列化和反序列化行为。为此,请创建一个实现或接口的类,并在需要自定义的字段或类上使用和注解。@Override// ...其他代码...优势性能优异:Jackson在序列化和反序列化过程中表现出优秀的性能,通常比其他Java JSON库更快。灵活性:通过注解、自定义序列化器/反序列化器等功能,Jackson提供了丰富的配置选项,允许你根据需求灵活地处理JSON数据。易于使用:Jackson的API设计简洁明了,易于学习和使用。

Swift中的问号?和感叹号!

Swift语言使用var定义变量&#xff0c;但和别的语言不同&#xff0c;Swift里不会自动给变量赋初始值&#xff0c;也就是说变量不会有默认值&#xff0c;所以要求使用变量之前必须要对其初始化。如果在使用变量之前不进行初始化就会报错&#xff1a; var stringValue : String …

拜托!别再滥用 ! = null 判空了!!

另外,也许受此习惯影响,他们总潜意识地认为,所有的返回都是不可信任的,为了保护自己程序,就加了大量的判空。如果你养成习惯,都是这样写代码(返回空collections而不返回null),你调用自己写的方法时,就能大胆地忽略判空)这种情况下,null是个”看上去“合理的值,例如,我查询数据库,某个查询条件下,就是没有对应值,此时null算是表达了“空”的概念。最终,项目中会存在大量判空代码,多么丑陋繁冗!,而不要返回null,这样调用侧就能大胆地处理这个返回,例如调用侧拿到返回后,可以直接。

ffmpeg java linux水印,Linux环境用FFmpeg给视频加水印详细步骤

FFmpeg给视频添加水印&#xff0c;根据官方文档的介绍可以知道FFmpeg在编译安装的时候还需要加 –enable-libfreetype、–enable-libfontconfig、 --enable-libfribidi 这几个参数&#xff0c;而这几个组件又需要从外面编译安装&#xff0c;我看很多博主直接用FFmpeg命令加水印…

red hat DHCP服务器配置

[ 基本操作 ] rpm –q dhcp / rpm -ql grep dhcp [ 查询DHCP ] yum –y install dhcp dhcp -devel service dhcpd start [ 启动 ] service dhcpd status [ 查看DHCP状态 ] chkconfig – level 3 5 dhcpd on [ 改变启动级别为3 5 自动启动服务 ] service ne…

axios解决调用后端接口跨域问题

vue-cli通过是本地代理的方式解决接口跨域问题的。但是在vue-cli的默认项目配置中这个代理是没有配置的&#xff0c;如果现在项目中使用&#xff0c;必须手动配置config/index.js文件 ... proxyTable: {/api: { //将www.exaple.com印射为/apistarget: https://www.example.c…

递归/归并:count of smaller numbers求逆序数

已知数组nums&#xff0c;求新数组count&#xff0c;count[i]代表了在nums[i]右侧且比 nums[i]小的元素个数。 例如: nums [5, 2, 6, 1], count [2, 1, 1, 0]; nums [6, 6, 6, 1, 1, 1], count [3, 3, 3, 0, 0, 0]; nums [5, -7, 9, 1, 3, 5, -2, 1], count [5, 0, 5, 1…

远程计划任务管理

有时你需要远程管理或运行一批机器&#xff0c;但是按要求你没有权限或者不能安装客户端&#xff0c;下面的批处理可能帮上你的忙&#xff0c;将下方代码保存为批处理&#xff0c;并创建Clients.txt&#xff0c;存放的是以回车分隔的IP echo off setlocal enabledelayedexpansi…

linux shell for 循环变量,shell for循环总结

1 shell for循环语法for 变量 in 列表docommand1command2...commandNdone1.1 读取列表中的值#!/bin/bashfor test in apple boy cat dogdoecho The next state is $testdone结果&#xff1a;The next state is appleThe next state is boyThe next state is catThe next state …

自定义堆栈(回文检测)

using System; using System.Collections;namespace CStack {class Program{static void Main(string[] args){CStack alist new CStack();string ch;string word "上海自来水来自海上";bool isPalindrome true;for (int x 0; x < word.Length; x){alist.Push…

二叉树(C++):创建,前中后序遍历(递归+非递归),获取叶子节点个数,获取树的高度

文章目录前言创建二叉树先序遍历中序遍历后序遍历获取叶子节点个数获取树的高度测试代码前言 现有如下二叉树: 关于二叉树的相关操作&#xff0c;我们能够发现二叉树从根节点到子节点&#xff0c;以及每个中间节点基本都能够拆分为若干个子节点的操作&#xff0c;且每个子节点…

6月11号=》121页-125页

6.1  样式单概述 W3C已经给出了两种样式单语言的推荐标准&#xff0c;一种是级联样式单CSS(Cascading Style Sheets)&#xff0c; 另一种是可扩展样式单语言XSL(eXtensible Stylesheet Language)。 6.1.1  CSS CSS主要提供如下两个功能&#xff1a; 1&#xff1a;对页面的字…

linux cp sync,通过SSH使用Rsync传输文件,复制和同步文件及目录

在本文中&#xff0c;我们将解释如何通过SSH使用rsync复制文件。当涉及在网络上的系统之间传输文件时&#xff0c;Linux和Unix用户可以使用许多工具&#xff0c;最流行的数据传输协议是SSH和FTP&#xff0c;虽然FTP很受欢迎&#xff0c;但总是喜欢使用SSH&#xff0c;因为它是传…

【Java笔记】C++与Java的对比

接口&#xff1a; C可以多重继承&#xff0c;而Java不可以。但是Java里一个类可以声明实现多个接口。

cf792b循环链表

头尾链接一下就好&#xff0c; /* 1 2 3 4 5 6 7:4 5 6 7 1 2 3:2 3 5 6 7 1:5 6 7 1 3:6 7 1 3:1 3 7 */ #include<bits/stdc.h> using namespace std; int main(){int n,k,q[200],nxt[200],p,pre,tot;scanf("%d%d",&n,&k);for(int i1;i&…

二叉树:路径之和 Path Sum

给定一个二叉树与整数sum&#xff0c;找出所有从根节点到叶结点的路径&#xff0c;这些路 径上的节点值累加和为sum 即创建一个二叉树&#xff0c;要求二叉树中有一个路径从根节点到叶节点到路径加起来代表到和为 给定的sum 如下二叉树 给定路径之和为18&#xff0c;则需要输…

从零开始编写自己的C#框架(16)——Web层后端父类

从零开始编写自己的C#框架&#xff08;16&#xff09;——Web层后端父类 原文:从零开始编写自己的C#框架&#xff08;16&#xff09;——Web层后端父类 本章节讲述的各个类是后端系统的核心之一&#xff0c;涉及到系统安全验证、操作日志记录、页面与按键权限控制、后端页面功能…

c语言中的普通字符包括什么,【判断题】C语言中的字符常量通常有两种形式:普通字符和转义字符。...

【判断题】C语言中的字符常量通常有两种形式:普通字符和转义字符。更多相关问题&#xff0d;&#xff0d;&#xff0d;Can you speak French&#xff1f;&#xff0d;&#xff0d;&#xff0d;Yes, but only____.A&#xff0e;a littleB&#xff0e;littleC&#xff0e;muchD&a…

Codeforces Round #104 (Div. 2) E DP(01背包模型) +组和+除法取模求逆元

题意&#xff1a; 规定只包含4或7的数为幸运数字&#xff0c;给定n个数的序列&#xff0c;求他的子序列&#xff0c;使得该子序列的长度为k并且满足该子序列中不存在相同的两个幸运数字。问一共寻在多少种可能。&#xff08;只要该数的下标不同则认为是不同的序列&#xff09; …

django 增加验证邮箱功能

在user文件夹下新建python包&#xff0c;utils 在包内新建文件email_send.py,其中包括验证字符串随机码的产生&#xff0c;数据库的存储和email的发送 # -*- coding: utf-8 -*- # 作者&#xff1a;神秘藏宝室 # 日期&#xff1a;2019/1/1 22:21 from random import Random from…

二叉树:最近的公共祖先 Lowest Common Ancestor of a Binary Tree

已知二叉树&#xff0c;求二叉树中给定的两个节点的最近公共祖先。 最近公共祖先: 两节点v与w的最近公共祖先u&#xff0c;满足在树上最低(离根最 远)&#xff0c;且v,w两个节点都是u的子孙。 如上二叉树&#xff0c;6和8号节点的公共祖先有4&#xff0c;1&#xff1b;但是最近…

VS不显示最近打开的项目

VS2012不显示最近打开的项目 解决方法&#xff0c; 在"运行"中输入 " gpedit.msc"打开后在"用户配置"-"管理模板"-"任务栏和开始菜单" 然后将用户配置-->管理模板-->不保留最近打开文档的历史 将此选项设置为禁用 源…

河科大c语言上机实验答案,2016年河南科技学院信息工程学院C语言上机编程考研复试题库...

一、选择题1&#xff0e; 以下选项中&#xff0c;能用作数据常量的是( )。答:D【解析】A 项错误&#xff0c;十六进制数用数学0和字符x (或大写字母X )开头&#xff1b;B 项错误&#xff0c;八进制整数常量以数字0开始&#xff0c;有效数字为0〜7; C项错误&#xff0c;C 语言中…

无符号数溢出之后

2019独角兽企业重金招聘Python工程师标准>>> [rootcentos ~]# cat test.c #include <stdio.h>int main() {unsigned short i 0x0;while(1){printf("%u \n",i);if(i 0) //溢出之后 又会回到 0 所以不会 死循环break;} } 转载于:https://my.oschin…

加载BeanFactory

前言 上一篇文章讲述了ApplicationContext扩展功能的之一&#xff1a;环境准备。这篇文章接着讲述ApplicationContext的扩展功能-----加载BeanFactory&#xff0c;也就是初始化BeanFactory&#xff0c;并进行XML文件的读取。 加载BeanFactory obtainFreshBeanFactory方法从字面…

t-top 命令详解

前言 展示操作系统进程信息。动态得&#xff0c;实时得展示正在运行的操作系统进程信息。 所显示的系统摘要信息的类型以及为进程显示的信息的类型&#xff0c;顺序和大小都是用户可配置的&#xff0c;并且可以使配置在重新启动后保持不变。该程序为流程操作提供了一个有限的交…

怎么看懂c语言程序,求讲解一下这个程序,我看了1个小时都没有看懂,

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼# include #define N 9void fun(int a[], int n){ int i,j, max, min, px, pn, t;for (i0; i{/**********found**********/max min ___a[i]__;px pn i;for (ji1; j/**********found**********/if (max<___a>{ max a[j];…

【转】Winform输入法控制

来源&#xff1a;http://blog.itpub.net/23109131/viewspace-630576 想实现输入法切换&#xff1a;思路&#xff0c;找出当前系统所有输入法总个数&#xff0c;当前输入法在总输入法中的索引&#xff0c;通过改变索引值&#xff0c;来切换输入法 void input() {//变全角为半角的…