排序算法系列——归并排序

记录学习点滴,菜鸟成长记

归并排序的英文叫做Merge-Sort,要想明白归并排序算法,还要从“递归”的概念谈起。

1.递归

一般来讲,人在做决策行事的时候是往往是从已知出发,比如,我又要举个不恰当的例子了→_→:

  • 看到漂亮姑娘→喜欢人家→追→女朋友→老婆

但是人家施瓦辛格不是这么想的,人家从小就立志当总统:

  • 要当总统←先当州长←竞选州长要有钱←那得找个有钱妹子←妹子都喜欢明星←身材好能当明星←健身

递归,就像一个人对自己的发展有清晰的规划和坚定的信心一样,他知道每一步会有怎么样的结果,他需要仅仅是一颗救命稻草,一旦抓住,最终结果是抱住参天大树。

 1 def f(n):#求一个数的阶乘
 2     if n==1:
 3         return 1
 4     else:
 5         return n*f(n-1)
 6 def F(willbe):#求我如何成为天下第一
 7     if willbe == canbe:
 8         return ‘be this‘
 9     else:
10         return willbe + F(willbe.needbe)
  • 类比于经典的递归应用,求一个数的阶乘,我写了一个求我如何成为天下第一。
  • 递归,我的理解就是前世因缘已经注定,要做的就是快速找到前世的因,也就是程序里的终止条件。

最后,我想说的是,要理解递归,你先要理解递归。这个出自:要理解递归,你需要先理解递归……

2.分治模式:

分治模式就不谈了,一般的分治法就是老生常谈的:分解、解决、合并

3.归并

下面我们来解释什么是归并,首先我们还是从那副扑克牌说起,你觉得一个人给扑克牌排序没啥意思,这时你叫上了一个朋友,将扑克牌分成两堆,约定各自排各自的,两人都排好自己的顺序后在合并,不一会你两就排好了。

怎么合并呢?其实很简单,你们把两摞扑克牌放在桌面上,开始比较每一摞最上面的牌,哪张牌最小你就拿起哪张,后拿起的牌放在先前拿起的牌的后面,不一会你两就将这副牌排好顺序了。

然后你觉得这个游戏很有意思,你又叫来了2个人,然后大家一起愉快的排扑克牌了;你觉得还是不够尽兴,于是又叫了50个人,这时每个人手里都有一张牌,由于人太多,不得不并了两张桌子来让大家坐下(假设一张桌子能做27个人,没看过哈利波特吗,XD...)。。。恩,大家还是把所有牌放在桌子上,由于人太多,你就安排了1个桌长,你两各负责一张桌子;你和小组长觉得还是管不过来,于是你两又各自在自己负责区域分了两个小组长,分下去的小组长也很懒,他们准备继续行使自己的权力,就这样分啊分,一共分了54个小组长,大家你看你,我看我。。。

不管了,你只负责你分的两个小组长,最后你和你认命的桌长一起完成此次艰巨的任务。

  • 写到这里的时候,我想起我当时看过的《三体》,脑海中浮起的是大刘给我们描述的三体人组成的计算机

4.实现

归并排序的关键是归并两个排好序的数组,按照《导论》使用Python实现如下

 1 def Merge(A,p,q,r):
 2     L = A[p-1:q+1-1]#p表示实际的下标,写完算法再-1
 3     R = A[q+1-1:r+1-1]
 4     temp = []
 5     while len(L) > 0 and len(R) > 0:
 6         if L[0] > R[0]:
 7             temp.append(R.pop(0))
 8         else:
 9             temp.append(L.pop(0))
10     if len(L) > 0:
11         temp.extend(L)
12     if len(R) > 0:
13         temp.extend(R)
14     A[p-1:r+1-1] = temp
15 def MergeSort(A,p,r):
16     if p<r:
17         q = (p+r)/2
18         MergeSort(A,p,q)
19         MergeSort(A,q+1,r)
20         Merge(A,p,q,r)
  • 这里必须吐槽一下:我是在Eclipse中用PyDev写的Python程序,尽然没有变量检测,由于输入中有个r,新建R最初写的是r,尽然没有报错,Debug了一下午才发现,看来还是心不静,曾记得看过一句话,说得十分在理,天下程序,唯慢不破。

5.更新

排序算法系列——归并排序,布布扣,bubuko.com

时间: 2024-07-31 14:31:37

排序算法系列——归并排序的相关文章

排序算法系列——堆排序

记录学习点滴,菜鸟成长记 堆排序引入了另一种算法设计技巧:使用一种我们称之为“堆”的数据结构来进行数据管理. 堆排序算是真正意义上的利用数据结构来求解数组排序的方法. “插入排序”和“归并排序”可以看做是一种“计算机体力活”,体现的思想更多的是去模拟最简单的人类思维,比如插入排序过程中的比较,归并中子问题合并时的比较. “堆排序”可以看做是“计算机脑力活”,他利用了一种结构化的语言来表达,这种结构化带来一些性质,比如左右孩子.比[堆大小的一半向下取整]大的下标都是叶节点不需要维护其最大堆性质等.

算法系列——归并排序

归并排序基本思路就是将数组分成二组A,B,如果这二组组内的数据都是有序的,那么就可以很方便的将这二组数据进行排序.如何让这二组组内数据有序了? 可以将A,B组各自再分成二组.依次类推,当分出来的小组只有一个数据时,可以认为这个小组组内已经达到了有序,然后再合并相邻的二个小组就可以了.这样通过先递归的分解数列,再合并数列就完成了归并排序. #include <iostream> #include <string> #include <algorithm> #include

(转载)排序算法系列

排序算法系列 目录 概述 概念 排序是计算机内经常进行的一种操作,其目的是将一组"无序"的记录序列调整为"有序"的记录序列. 排序分为内部排序和外部排序. 若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序. 反之,若参加排序的记录数量很大,整个序列的排序过程不可能在内存中完成,则称此类排序问题为外部排序. 排序分类 如果按照策略来分类,大致可分为:交换排序.插入排序.选择排序.归并排序和基数排序.如 图-排序策略分类图 所示. 图-排序策略分类图 算

常用排序算法之——归并排序

归并排序的原理: 如果数组的元素个数大于1,则: 将数组平均分为两部分: 左边的数组归并排序:递归 右边的数组归并排序:递归 将两个各自有序的数组合并,需要一个额外的辅助数组,暂时保存合并结果:返回 否则,数组元素个数为1时,已经有序:直接返回. 稳定排序.时间复杂度在最坏.最好.平均情况下都为O(N lgN),空间复杂度为O(N). 代码: 1 #include <iostream> 2 using namespace std; 3 4 template<typename T>

排序算法系列——快速排序

记录学习点滴 快速排序算法是一种很有趣的算法,短小精悍,性能强劲,对于大部分情况都可以胜任,但对极端环境难以应付. 快速排序我理解为:这是一个“以自我为中心的”+“分治法”思想的算法. 分治法不必多说,化繁为简,那就是逐个击破. 那什么是“以自我为中心”?顾名思义,就是每次都一个“我”,每个人都要围绕“我”行事,比“我”小的都去左边站着,比“我”他大的都去右边站着,而且“我”不去关心每一边都有谁,反正你没“我”大或者小就行.一旦“我”落位了妥帖了,“我”就不动了.然后再在左右两边分别产生新“我”

Java常见排序算法之归并排序

在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let‘s go~~~ 1.排序算法的基本概念的讲解 时间复杂度:需要排序的的关键字的比较次数和相应的移动的次数. 空间复杂度:分析需要多少辅助的内存. 稳定性:如果记录两个关键字的A和B它们的值相等,经过排序后它们相对的位置没有发生交换,那么我们称这个排序算法是稳定的. 否则我们称这个排序算法是不稳定的

排序算法系列——插入排序

记录学习点滴,菜鸟成长记 接触算法是研究生期间做项目时,需要编写一些诸如GA.QGA的时候,第一次使用“排序”还是用的Java自带的Comparator接口.后来买了<算法导论>来看,发现果然所有知识都是有专业壁垒的,简单的一个问题尽然蕴藏着如此多的思想,发现此简直欣喜无比,遂决定要好好研究研究.只有深入后才发现,原来算法的不仅仅是按照逻辑顺序写个程序那么简单,好的算法要考虑到方方面面,最简单的时间复杂度就够我学习很长时间了. 将自己学习排序算法的一些理解和感悟记录于此,方便自己温故而知新.

排序算法系列——八大排序算法对比分析

本系列最后一篇,综合分析下前面介绍的八种排序算法的效率,以及各自的适用情况. 下面先看看八种排序算法的时间复杂度表格: 图中八种排序被分成了两组,一组时间复杂度为O(n^2),另一组相对高效些. 下面先对第一组O(n^2)的四种排序算法进行对比,分别取数组长度为100,1000,10000,100000四个数量级,各个元素在0-10000000之间随机获取.下面看下结果的分析. 排序算法 长度=100 长度=1000 长度=10000 长度=100000 直接插入排序 535 2,198 135

经典排序算法系列7----堆与堆排序

堆排序与快速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法.学习堆排序前,先讲解下什么是数据结构中的二叉堆. 二叉堆的定义 二叉堆是完全二叉树或者是近似完全二叉树. 二叉堆满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值. 2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆). 当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆.当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆.下图展示一个最小堆: 由于其它几