c++两个vector合并_数据结构——算法初步(4)——合并排序算法

从之前的学习可以看到,对大型vectory要求的排序,选择排序算法显然不符合要求,因为运行时间与输入问题规模大小的平方成比例增加,对于以线性顺序处理向量的元素的大多数排序算法也是如此。 所以要采用不同的方法来开发更好的排序算法。我们可以试着反过来思考。

强大的分治法(divide-and-conquer)

分治法的具体详见 C++抽象编程——递归简介(1)——递归范式 我们先来看看排序算法的性能为什么在问题规模增大后变得如此糟糕?我们之前分析过二次复杂度(即O(N^2)类)的基本特征是,随着问题的大小增加,运行时间增加了问题规模的两倍(比如问题规模增加2倍,那么运行时间要增加4倍)然而,反过来我们可以这样想。 如果将二次问题的大小除以2,则可以将运行时间减少相同的四倍。 也就是说我们可以将vector除以一半,然后应用递归的方法继续将问题的规模拆分,就可以成倍的减少所需的排序时间。

举个例子,假设你有一个很大的vector需要排序。如果将vector分成两半,然后使用选择排序算法对这些片段进行排序,会发生什么? 因为选择排序是的复杂度是二次的,每个较小的vector需要原始时间的四分之一(问题规模减少了2倍,时间就提高4倍)。 当然,你需要对这两半分别进行排序,但是排序两个较小vector所需的总时间仍然是排序原始vector所需的时间的一半。如果分开一个vector的两半可以简化整个vector排序的问题,我们将能够大大减少排序需要的总时间。更重要的是,一旦发现如何在一个地方提高性能,就可以使用相同的算法递归地对每一个进行排序。 为了确定分治法是否适用于这个排序问题,我们需要确定一个问题,即将vector分为两个较小的vector,然后对每个vector进行排序是否有助于解决一般问题(也就是拿一个实例来分析一下)。假设你从一个包含以下八个元素的vector开始排序:

97bb542772bfd7324be35aaeef1e449d.png

如果将8个元素的vector划分为长度为4的两个vector,然后对每个较小的vector进行排序,就会得到下图:

294e9c79b87a97ed8803981ec58eeb0a.png

现在我们需要从这些较小的vector中取出值,并将它们以正确的顺序放回到原始vector中。

合并两个vector

从较小的排序vector重组成完整的vector比排序本身要简单得多。这个过程我们称为合并(merging)即完整排序中的第一个元素必须是v1中的第一个元素或v2中的第一个元素,以较小者为准。回到这个例子当中, 1. 我们新组成的的vector中的第一个元素是第二个vector(v2)中的第一个元素。然后将该元素添加到空的向量vec,此时我们把v2的19叉掉,表示已经取出,我们下图的结果

a8c4e067854a93c87f1ad14b0987a662.png

2. 再来一次,下一个元素只能是两个较小向量之一中的第一个未取出的元素。比较v1中的25与v2中的30,并选择前者:

ce170f5864e466ef46189e3a0b999b95.png

3. 重复此过程,从v1或v2中选择较小的值,直到重构整个vector

合并排序算法

合并操作与递归分解相结合,产生了一种称为合并排序的新的排序算法,可以直接实现。 算法的基本思想可以概括如下:

1. 检查vector是否为空或只有一个元素。如果是这样,它肯定已经被排序。此条件用于定义递归的simple case。

2. 将vector分成两个较小的vector,每个vector的大小是前者的一半(意味着,不是值分成两个vector,而是每个分开的vector还可以继续分,重复这个过程)

3. 递归地对每个较小的vector进行排序。

4. 清除原始的vector,使其再次为空。(用来储存新的排序好的数字)

5. 将两个排序好的vector合并回原来的vector。

合并排序的C++代码

合并排序思路简单,但是实现起来并不那么容易,下面是本人写的C++代码,在VS2015中编译通过:

/*

运行效果如图:

2215139d0809726a08bd711156c9c51b.png

合并排序算法的代码可以整齐地分为两个函数:排序和合并。 排序代码直接来自算法的步骤。在检查特殊情况后,算法将原始vector分为两个较小的v1和v2。一旦sort代码将所有元素复制到v1或v2中,v1,V2就已经被创建,其余的函数会递归地排序这些vector,最后清除原始vector,然后调用merge来重新组合vector,从而实现合并排序。 实际上大部分的工作是通过合并函数完成的,该函数采用目标vec,以及较小的向量v1和v2。指标p1和p2标记跟踪每一个vector的下标。 在循环的每个循环中,该函数从v1或v2选择一个元素取较小者,并将该值添加到vec的末尾。一旦两个较小的vector中的任何一个的元素被取尽,该函数可以简单地从另一个vector中直接复制元素而再比较它们。实际上,因为这些向vector中的其中一个已经在第一个while循环退出时已经耗尽,所以该函数可以将vector的其余部分复制到vec。 其中一个vector为空,相应的while循环将完全不执行。

这里说一下,v1[p1++],其实我们都知道 i++返回的 i的值是自增1的。但是这个运算符返回的是自增前的值。也就是说比如 i = 2,执行

i++;

之后,就是 i = 3,但是 (i++)这个整体的值就还是 2(可以写个程序试试)。 所以说

v1[p1++]

这句代码等价于:

 v1[p1]; p1 ++;

下一篇的文章我们就去分析一下这个算法的复杂度

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

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

相关文章

asterisk 互联

如上图所示,两个sip客户端分别注册在A,B两个asterisk服务器下,让A和B通过各自的asterisk服务器来相互通信。 xlite A的账号为2001,xlite B的账号为5001 asterisk A的sip.conf如下配置: [general] contextunauthenticated allow…

dll文件懒加载_一步步学习NHibernate(5)——多对一,一对多,懒加载(2)

请注明转载地址:http://www.cnblogs.com/arhat通过上一章的学习,我们建立了Student和Clazz之间的关联属性,并从Student(many)的一方查看了Clazz的信息,同时我们使用了懒加载技术和立即执行的方式来实现了对象的关联查询&#xff0…

python代码加密 混淆_Python程序的混淆和加密

混淆 为了增加代码阅读的难度, 源代码的混淆非常必要, 一个在线的Python代码混淆网站. 如果你觉得有用, 可以购买离线版本. 同时需要注意的是, 这个混淆其实还是被很多人怀疑的, 因为即使混淆了, 也没有改变代码的结构. 所以, 必要的话, 在编程的时候, 可以故意做点提高逆向难度…

[活动通知]Nanjing GDG 2013年4月活动

致各位亲爱的 Google 技术爱好者 很高兴的通知各位朋友,Nanjing GDG 将在本周日 (04/21) 举办我们 Nanjing GDG 的 4月份活动,热烈欢迎大家报名参加。 主题:利用开放社区和代码库来构建 Android 应用 时间: 4月21 日 (周日) 下午 …

python linux运维教程 推荐_Linux运维人员成长之路学习书籍推荐

原标题:Linux运维人员成长之路学习书籍推荐一、入门书:《鸟哥的私房菜(基础篇)》《鸟哥的私房菜(服务篇)》《Linux命令行与Shell脚本编程大全(第2版)》《UNIX/Linux 系统管理技术手册》《UNIX编程艺术》二、计算机及操作系统原理书:《深入理解…

MySQL笔记——外键约束和表关系(一对一,多对一,多对多)

一、外键约束 概念:外键用来让两个表的数据之间建立链接,保证数据的一致性和完整性。语法:(1)添加约束-- 创建表是添加外键约束CREATE TABLE 表名(列名 数据类型,…[CONSTRAINT] [外键名称] FOREIGN KEY(外键列名) REF…

asterisk 学习笔记1

一: Asterisk为特定的目标指定了一些extension名称。 i:Invalid s:Start h:Hangup t:Timeout T:AbsoluteTimeout o:Operator 一般常用的是i和t 二: asterisk拨号方案的调试可以用NoOp()函数,这个函数什么也不做,…

hashCode()方法的作用使用分析

一直以来都想写篇文章来说明下hashCode的作用以及相关的知识,许久没动笔,最近找了点资料,自己整理了一下,于是就诞生了下面的东西! (1)前言,想要明白hashCode的作用,你必须要先知道Java中的集合…

仿个人税务 app html5_【注意】你下载的可能是个假的个税App

新个税法从1月初开始实施。国家税务总局推出“个人所得税”APP,方便纳税人线上填报资料进行专项抵扣。几天来,这款APP的下载量和注册量大幅增长。随之而来的是,很多商业公司制作的各类“个税”APP也成为热门。这其中有不少纯属蹭热点&#xf…

MySQL笔记——多表查询

多表查询不能使用 SELECT * from emp, dept; 会产生笛卡尔积。 笛卡尔积,有A,B两个集合,A中有5条信息,B中有4条信息,那么查询结果就是5*420条一、内连接查询 -- 隐式内连接SELECT 字段列表 FROM 表1,表2,… WHERE 条件…

遇见王沥川的人生感悟_23岁酱油泡饭默默无闻,31岁逆袭人生,王彦霖有何魅力?...

文/小白说娱S姐 原创精品,请勿转载如果兜里只剩下1块钱,生活所迫你会怎样过?王彦霖23岁刚毕业熬过了1元危机,他永远都不会想到当年咬牙坚持熬成就了如今的综艺诸葛。《元气满满的哥哥》连播六期多次排名第一,成为芒果台…

antd vue form 手动校验_参与《开课吧》vue训练营笔记(Day1)

大神说的目标:Vue 挑战20k组件间通信component 官网 详解组件间的传递方式:父传子 直接属性传递子传父 this.$emit 时间传递兄弟组件 利用父组件搭桥组件和子孙 provide / inject子孙 -> 祖先 this.$dispatch 或provide 获取组件元素实例$listeners $…

细学PHP 14 mysql-4

预留转载于:https://www.cnblogs.com/cnmice/archive/2013/04/17/3027102.html

Asterisk针对Mysql的extconfig.conf配置

Asterisk针对Mysql的extconfig.conf配置,这其中涉及到的表的structure [setting] sipusers > mysql,general,sip_buddies sippeers > mysql,general,sip_buddies queues > mysql,general,queue_table queue_members >mysql,general,queue_member_tabl…

ipfs 云服务器_IPFS加速云服务生机和分布式存储

如果能把一个安卓系统或IOS系统安装到分布式存储里,不管人们在做什么,各项数据都可以通过面部识别就可以确认ID,数据的响应性快,安全性和便捷性更高。IPFS的节点上,未来访问网站不再需要HTTP,而是IPFS。分布…

MySQL笔记——打开日志

在my.ini文件中输入如下命令:log_outputFILE general_logon general_log_file"D:\\SoftwareTools\\Mysql\\mysqllog\\mysql.log" slow_query_logon long_query_time 2 slow_query_log_file"D:\\SoftwareTools\\Mysql\\mysqllog\\mysql_slow.log"…

链表怎么输出最后一个元素无空格_剑指offer系列----从尾到头打印链表

从尾到头打印链表信息卡片时间:2020-03-23题目:从尾到头打印链表tag:list题目描述输入一个链表,按链表从尾到头的顺序返回一个 ArrayList。01调用 reverse 函数解题思路这是一种简单粗暴的解法。先遍历一遍链表,在遍历…

a20_v2.0_k70运行在xhda20开发板

修改sys_config.fex文件两个地方 [clock] pll3 297 pll4 300 pll6 600 pll7 297 pll8 336 [dram_para] dram_baseaddr 0x40000000 dram_clk 408 d…

EntiyFramework :Update model from database引起的两个问题

EntiyFramework一大特点就是Code first,但难免有时候因特殊原因需要Update model from database。此次使用该功能时遇到两个问题,且记之。 [问题一] Error 3027: No mapping specified for the following EntitySet/AssociationSet - XXXXXXX. [起因] 在…

MySQL笔记——JDBC入门

(一)JDBC简介 JDBC概念:(1)JDBC就是使用Java语言操作关系型数据库的一套API(2)全称:(Java DataBase Connectivity)Java数据库连接(二)…