请教下,两个列表都是按照一定要求排好序,有什么算法能使区间合并算法后的列

您的举报已经提交成功,我们将尽快处理,谢谢!
void reverse_merge(LinkList A,LinkList B,LinkList *C)
{ LinkList pa,pb,
大家还关注关注上方“九章算法”获取更多求职必备干货题目描述&两个已排好序的数组,找出两者合并后的数组的中位数。Example给出 A=[1,2,3,4,5,6] 和 B=[2,3,4,5],他们合并后的中位数是 3.5((3+4)/2)。给出 A=[1,2,3] 和 B=[4,5],他们合并后的中位数是 3。解题思路分析&这道题的直观解法:就是扫一遍两个数组,找到中间位置的那一个/两个数,然后得到中位数。时间复杂度是 O(m+n),其中 m 和 n 分别是数组 A 和数组 B 的长度。但是!面试官会这么轻易就放过你吗?显然是不可能滴~~我偷看了一下题目描述下的“challenge”标签,原来这道题的最优解是 O(log(m + n)) 的复杂度。(m + n) 是俩数组合并后的总长度 &L,看到 O(log L) 这样的复杂度,而且还是有序数组,能想到哪个算法吗?没错,就是二分查找!那我们试试。。1. 如果我取出 A[i] ,用二分查找在数组 B 中找到 A[i] 可以插入的位置,假设 A[i] 在 B 中的插入位置是 j,那么 A[i] 在整个合并数组中的位置就是 (i + j) ,因为要求的中位数的位置是 (m + n) / 2,通过比较 (i + j) 和 (m + n) / 2 的大小可以每次舍弃 A 的一部分,从而收敛数组 A。用同样的方法可以收敛数组 B。但是这样的复杂度是 O(log m * log n),复杂度大于 O(log(m + n)),显然不是最优的。2. 那如果不是直接使用二分查找算法,而是借用二分查找的思想呢?就是每次有选择地舍弃掉数组的一部分,从而达到收敛数组缩小查找范围的效果。a. 我们重新看题目,要找中位数,就是要找第 k 大的数(k = (L / 2 + 1),其中L 是上面提到的合并后新数组的长度,当 L 是偶数时,要求第 (L / 2) 大和第 (L / 2 + 1) 大的两个数)。当我们舍弃掉一部分,假设舍弃部分的长度为 length,那么接下来就是在剩下的数组里求第 (k - length) 大的数。逐层缩小范围,直到两数组其中一个走完,或者要求的是第 1 大的元素,就可以直接返回结果了。b. 那如何“选择”要舍弃哪部分呢?既然是要找合并后的数组 C 的第 k 大元素,即 C[k-1],那如果我们从 A 和 B 中分别取前 k/2 个元素,其中必然有一部分是是在数组 C 的前 k 个数里。设 mid = k / 2,当 A[mid - 1] & B[mid - 1] 时,可以断定 A 的前 mid 个元素是在 C 的前 k 个数里(此处可用反证法得证),那么我们则舍弃 A 的前 mid 个元素。反之则舍弃 B 的前 mid 个元素。现在数组 A 或者 B 已经舍弃掉 k/2 个元素,缩小查找范围了,那接下来可以按照同样的方法继续选择吗?当然!现在剩下总共 (L - mid) 个元素,且 A 和 B 依旧有序,要找的是第 (k - mid) 大的元素,所以我们可以按照上面的方法继续递归选择下去,直到找到目标元素!c. 复杂度分析:每次从合并后数组 C 里减少 k/2 个元素,直到找到目标元素。所以时间复杂度是 O(log L) = O(log (m + n)) !参考程序&面试官角度分析&这道题主要考察的是二分方法的拓展运用,并且需要对二分有比较高的理解,比如怎么样通过猜测试一试二分来解决问题。如果能够使用二分的方法,当然必然是Strong Hire的级别。LintCode相关练习题目/zh-cn/problem/median/最新面试题 & 解答:点击可阅读简介九章算法,帮助更多中国人找到好工作!九章算法,团队成员均为硅谷和国内顶尖IT企业工程师。提供算法培训、面试咨询、求职内推。目前开设课程有九章算法班、系统设计班、Java入门与基础算法班、九章算法强化班。更有android/big data/ios 等即将开课。目前培训的程序员遍布中国、美国、加拿大、澳大利亚、英国、新加坡等14个国家和地区。更多详情,登录,或致信.九章算法(ninechapter) 
 文章为作者独立观点,不代表微头条立场
的最新文章
题目描述给出一个链表,每个节点包含一个额外增加的随机指针可以指向链表中的任何节点或空的节点。返回一个深拷贝的简介九章算法,帮助更多中国人找到好工作!九章算法,团队成员均为硅谷和国内顶尖IT企业工程师。提供算法培训、面她 GPA没到3.5, 缺乏项目和实习经验,曾经简历一路被拒。但最终不断修改,问各种同学,问上班的人的意见,讲座时间:美西时间 8月28日 周日 10:00-11:30(a.m)美东时间 8月28日 周日 13:00面试官在Onsite主要考察你的哪些能力?面试者10大容易忽视的面试细节Onsite Coding 四要四不xx职场老司机:如何准备 Onsite 面试?10 Slides订阅上方“九章算法”获取最新IT求职干货Part1动态规划基本上就是说:你追一个MM的时候,需要对该MM身边题目描述给定一个正整数(int类型),判断这个整数是否是某个数的平方。不允许使用任何内置函数如sqrt直接计总结多年面官经验总结,教你如何写好技术简历,提升简历的通过率,以及如何避免在简历中给自己挖“坑”。CS硕士,曾经学渣一枚,简历一路被拒,最终经过多次简历修改,拿到wayfair, cerner, TwoSigma, LeEco, Google, Amazon等公司面试机会,最终签约 Amazon系统设计评分标准最新Uber面试题,附解答,面试官点评今天微软史上最大的收购案,Linkedin 被微软用262亿美刀买下,上个星期还是$131.08每股的Lin经常有童鞋说:我题目都做出来了,为啥还是挂了呢?面试挂掉的原因是多种多样的。有时候,仅仅一个“小小”细节上的Google 面试题,附解题思路 & 参考代码。Instagram Tech Blog 官方文章翻译。欢迎投稿:)某次旅行后小九留下了若干张飞机票,每张飞机票上写有出发和到达的机场名。他出发的机场是“JFK”,他希望知道自己旅行时的准确路线。今天给大家带来某学员在加州的Facebook和Google Onsite面经!总体而言,笔者认为google2016年4月,九章学员面试真题,附答案签约offer: Google; 拿到offer: Google, eBay, Pennypop快速排序与归并排序的参考程序uber最新面试题,及答案。九章学员小包子,放弃科研,CS求职经验。友谊的小船说翻就翻 T TRemove duplicate lines of a file.
What if the file is very large which could not be held in the main memory?首先所有的要提交的代码都需要经过审批系统设计面试真题,附答案。题目描述给出一个无序的整数序列,返回是否存在递增的三元组子序列。即返回true,如果存在i,j,k使得arr<img src="/Static/Img/loading.png" class="imglazy" data-original="/?url=/mmbiz/hK6krTdpF7sALfkwCqOthBFbe3ClMEG8v8LVFbAYZXsOiaWXNe732jx66uicmMw41Fpv5fylESfVgysJaqWLKGfQ/0?wx_fmt=jpeg"
alt="Offer收割机的求职秘诀 | 讲座精华总结" title="Offer收割机的求职秘诀 | 讲座精华总结"
width="210" height="105">二叉树经典题目及解答xxxGoogle 2016 面试题,附答案和参考代码。Google 2016 面试题,附解答。(点击上方关注九章算法,获取最新IT求职干货!)今天面了google,也是最近面试非常重要的一次,从昨天晚上题目描述给出一个数字矩阵,寻找一条最长上升路径,每个位置只能向上下左右四个位置移动。Example:nums给出一棵二叉树,找出其最大的二叉搜索子树,最大指包含的点数最多。题目描述给出一个整数数组nums,重新排列nums使得nums[0]
nums[2]2016 Google 面试真题,附解答。金融公司更看重 communication 等 soft skills, 因此要注重准备 Resume-related Questions 和 Behavior Questions.Google 最新面试题,附解答。(点击上方关注九章算法,获取最新IT求职干货!)楼教主入职Quora啦,来听听他从Google跳槽到Quor如何刷题?
如何找内推?
如何联系Recruiter?
如何与面试官沟通?题目给出飞机的起飞和降落时间的列表,用 interval 序列表示. 请计算出天上同时最多有多少架飞机?在线九章学员转专业求职经验分享,拿到offer包括:
Internship: JP Morgan & Amazon
fulltime: Bloomberg2016年拿更多的offer!
抽中 H1B!
有一个美腻的妹子相伴!2015.12 Uber 面经题目一对整数是相亲数是说他们各自的所有有效因子(除了自己以外的因子)之和等于另外一个数。比如(220, 28签约offer: snapchat
拿到offer: snapchat, yammer“九章君听说最近好多小童鞋都要回国去过圣诞了。想到好多小童鞋回国去肯定要 renew H1B签证,九章君就给日前,符合条件的STEM专业的童鞋仍可申请17个月OPT Extension.ninechapter定期发布面试题,答案,面经。由Facebook/Google在职工程师维护。内推北美公司请发简历到,简历合格的我们会联系你。热门文章最新文章ninechapter定期发布面试题,答案,面经。由Facebook/Google在职工程师维护。内推北美公司请发简历到,简历合格的我们会联系你。说明:本文仅供学习交流,转载请标明出处,欢迎转载!
& & & & && &&题目:已知有两个有序的单链表,其头指针分别为head1和head2,实现将这两个链表合并的函数:
& & & & & Node* ListMerge(Node *head1,Node *head2)
& & & &这个算法很像我们排序算法中的归并排序,只能说&很像&,因为思想是一样的,但是这个与归并排序还是有区别的,区别如下:
&&& & &1.归并排序是针对有序数组,而这里是有序链表;
& & & &2.归并排序排序的时间复杂度为o(nlogn),而这里的时间复杂度最坏情况下为O(m+n),最好的情况下为O(min{m,n})。
& & & &3.归并排序需要重新申请空间,而这里无需再重新申请空间,只需改变链表结点的指针指向。
& & & &而这里算法的思想跟归并排序是一样的,都是对两个待归并的线性表分别设置1个指针,比较这两个当前指针的大小,将小的结点加入到合并后的线性表中,并向后移动当前指针。若两个线性表中,至少有一个表扫描完,走将对应的另一个表之间整体添加到合并后的线性表中。在这里:链表和数组的区别在于,链表只需要改变当前合并序列尾指针的位置,而数组则要将剩下的值依次复制到归并表的尾部。
& & & &&算法的递归实现如下:
Node&*ListMerge1(Node&*head1,Node&*head2)
&&&&if(head1==NULL)&&
&&&&&&&&return&head2;&&
&&&&if(head2==NULL)&&
&&&&&&&&return&head1;&&
&&&&Node&*head=NULL;&&
&&&&if(head1-&value&&&head2-&value)&&
&&&&&&&&head=head1;&&
&&&&&&&&head-&next=ListMerge1(head1-&next,head2);&&
&&&&else&&
&&&&&&&&head=head2;&&
&&&&&&&&head-&next=ListMerge1(head1,head2-&next);&&
&&&&return&&&
& & & &&&算法的非递归实现如下:
Node&*ListMerge(Node&*head1,Node&*head2)&&
&&&&if(!head1)&return&head2;&&
&&&&if(!head2)&return&head1;&&
&&&&Node&*head=NULL;
&&&&Node&*p1=head1;
&&&&Node&*p2=head2;
&&&&if(head1-&value&head2-&value)&&
&&&&&&&&head=head1;&&
&&&&&&&&p1=head1-&&&
&&&&else&&
&&&&&&&&head=head2;&&
&&&&&&&&p2=head2-&&&
&&&&Node&*p=
&&&&while(p1&&&&p2)
&&&&&&&&if(p1-&value&p2-&value)&&
&&&&&&&&{&&
&&&&&&&&&&&&p-&next=p1;&&
&&&&&&&&&&&&p1=p1-&&&
&&&&&&&&}&&
&&&&&&&&else&&
&&&&&&&&{&&
&&&&&&&&&&&&p-&next=p2;&&
&&&&&&&&&&&&p2=p2-&&&
&&&&&&&&}&&
&&&&&&&&p=p-&&&
&&&&if(p1)
&&&&&&&&p-&next=p1;&&
&&&&else&if(p2)
&&&&&&&&p-&next=p2;&&
&&&&return&&&
& & & & &&整个测试代码如下:
#include&iostream&&&
using&namespace&&&
struct&Node&&
&&&&int&&&
&&&&Node*&&&
&&&&Node(int&v):value(v){}&&
Node*&CreateList1()
&&&Node&*&&
&&&Node&*n1=new&Node(1);&&
&&&Node&*n3=new&Node(3);&&
&&&Node&*n5=new&Node(5);&&
&&&Node&*n7=new&Node(7);&&
&&&Node&*n9=new&Node(9);&&
&&&head=n1;&&
&&&n1-&next=n3;&&
&&&n3-&next=n5;&&
&&&n5-&next=n7;&&
&&&n7-&next=n9;&&
&&&n9-&next=NULL;&&
&&&return&&&
Node*&CreateList2()
&&&Node&*&&
&&&Node&*n2=new&Node(2);&&
&&&Node&*n4=new&Node(4);&&
&&&Node&*n6=new&Node(6);&&
&&&Node&*n8=new&Node(8);&&
&&&head=n2;&&
&&&n2-&next=n4;&&
&&&n4-&next=n6;&&
&&&n6-&next=n8;&&
&&&n8-&next=NULL;&&
&&&return&&&
void&FreeList(Node&*head)
&&&&if(head==NULL)&&
&&&&&&&&return&;&&
&&&&else&&
&&&&&&&&Node&*temp=head-&&&
&&&&&&&&delete&&&
&&&&&&&&head=&&
&&&&&&&&FreeList(head);&&
void&VisitList(Node&*head)
&&&&if(head)&&
&&&&&&&&cout&&head-&value&&"-&";&&
&&&&&&&&VisitList(head-&next);&&
&&&&else&&
&&&&&&&&cout&&"null"&&&&
Node&*ListMerge(Node&*head1,Node&*head2)&&
&&&&if(!head1)&return&head2;&&
&&&&if(!head2)&return&head1;&&
&&&&Node&*head=NULL;
&&&&Node&*p1=head1;
&&&&Node&*p2=head2;
&&&&if(head1-&value&head2-&value)&&
&&&&&&&&head=head1;&&
&&&&&&&&p1=head1-&&&
&&&&else&&
&&&&&&&&head=head2;&&
&&&&&&&&p2=head2-&&&
&&&&Node&*p=
&&&&while(p1&&&&p2)
&&&&&&&&if(p1-&value&p2-&value)&&
&&&&&&&&{&&
&&&&&&&&&&&&p-&next=p1;&&
&&&&&&&&&&&&p1=p1-&&&
&&&&&&&&}&&
&&&&&&&&else&&
&&&&&&&&{&&
&&&&&&&&&&&&p-&next=p2;&&
&&&&&&&&&&&&p2=p2-&&&
&&&&&&&&}&&
&&&&&&&&p=p-&&&
&&&&if(p1)
&&&&&&&&p-&next=p1;&&
&&&&else&if(p2)
&&&&&&&&p-&next=p2;&&
&&&&return&&&
Node&*ListMerge1(Node&*head1,Node&*head2)
&&&&if(head1==NULL)&&
&&&&&&&&return&head2;&&
&&&&if(head2==NULL)&&
&&&&&&&&return&head1;&&
&&&&Node&*head=NULL;&&
&&&&if(head1-&value&&&head2-&value)&&
&&&&&&&&head=head1;&&
&&&&&&&&head-&next=ListMerge1(head1-&next,head2);&&
&&&&else&&
&&&&&&&&head=head2;&&
&&&&&&&&head-&next=ListMerge1(head1,head2-&next);&&
&&&&return&&&
int&main()&&
&&&&Node&*head1=CreateList1();&&
&&&&Node&*head2=CreateList2();&&
&&&&cout&&"归并前"&&&&
&&&&cout&&"链表1:";&&
&&&&VisitList(head1);&&
&&&&cout&&"链表2:";&&
&&&&VisitList(head2);&&
&&&&cout&&"合并后的链表:";&&
&&&&Node&*head=ListMerge1(head1,head2);&&
&&&&VisitList(head);&&
&&&&FreeList(head);&&
&&&&return&0;&&
& & & &&&&测试结果如下:
参考资料-------------《剑指offer》
阅读(...) 评论()&#xe621; 上传我的文档
&#xe602; 下载
&#xe60c; 收藏
该文档贡献者很忙,什么也没留下。
&#xe602; 下载此文档
正在努力加载中...
NOIP基础算法——贪心和分治pascal
下载积分:3000
内容提示:NOIP基础算法——贪心和分治pascal,分治算法,分治算法的效率,分治算法 递归,什么是贪心算法,贪心算法 顶点覆盖,贪心算法,贪心算法的基本思想,贪心算法 例题,贪心算法 动态规划,贪心算法 java
文档格式:PPT|
浏览次数:24|
上传日期: 10:39:19|
文档星级:&#xe60b;&#xe612;&#xe612;&#xe612;&#xe612;
该用户还上传了这些文档
NOIP基础算法——贪心和分治pascal
官方公共微信合并排序,顾名思义,就是通过将两个有序的序列合并为一个大的有序的序列的方式来实现排序。合并排序是一种典型的分治算法:首先将序列分为两部分,然后对每一部分进行循环递归的排序,然后逐个将结果进行合并。
合并排序最大的优点是它的时间复杂度为O(nlgn),这个是我们之前的选择排序和插入排序所达不到的。他还是一种稳定性排序,也就是相等的元素在序列中的相对位置在排序前后不会发生变化。他的唯一缺点是,需要利用额外的N的空间来进行排序。
合并排序依赖于合并操作,即将两个已经排序的序列合并成一个序列,具体的过程如下:
申请空间,使其大小为两个已经排序序列之和,然后将待排序数组复制到该数组中。
设定两个指针,最初位置分别为两个已经排序序列的起始位置
比较复制数组中两个指针所指向的元素,选择相对小的元素放入到原始待排序数组中,并移动指针到下一位置
重复步骤3直到某一指针达到序列尾
将另一序列剩下的所有元素直接复制到原始数组末尾
该过程实现如下,注释比较清楚:
private static void Merge(T[] array, int lo, int mid, int hi)
int i = lo, j = mid + 1;
//把元素拷贝到辅助数组中
for (int k = k &= k++)
aux[k] = array[k];
//然后按照规则将数据从辅助数组中拷贝回原始的array中
for (int k = k &= k++)
//如果左边元素没了, 直接将右边的剩余元素都合并到到原数组中
if (i & mid)
array[k] = aux[j++];
}//如果右边元素没有了,直接将所有左边剩余元素都合并到原数组中
else if (j & hi)
array[k] = aux[i++];
}//如果左边右边小,则将左边的元素拷贝到原数组中
else if (aux[i].CompareTo(aux[j]) & 0)
array[k] = aux[i++];
array[k] = aux[j++];
下图是使用以上方法将EEGMR和ACERT这两个有序序列合并为一个大的序列的过程演示:
合并排序有两种实现,一种是至上而下(Top-Down)合并,一种是至下而上 (Bottom-Up)合并,两者算法思想差不多,这里仅介绍至上而下的合并排序。
至上而下的合并是一种典型的分治算法(Divide-and-Conquer),如果两个序列已经排好序了,那么采用合并算法,将这两个序列合并为一个大的序列也就是对大的序列进行了排序。
首先我们将待排序的元素均分为左右两个序列,然后分别对其进去排序,然后对这个排好序的序列进行合并,代码如下:
public class MergeSort&T& where T : IComparable&T&
private static T[] // 用于排序的辅助数组
public static void Sort(T[] array)
aux = new T[array.Length]; // 仅分配一次
Sort(array, 0, array.Length - 1);
private static void Sort(T[] array, int lo, int hi)
if (lo &= hi) return; //如果下标大于上标,则返回
int mid = lo + (hi - lo) / 2;//平分数组
Sort(array, lo, mid);//循环对左侧元素排序
Sort(array, mid + 1, hi);//循环对右侧元素排序
Merge(array, lo, mid, hi);//对左右排好的序列进行合并
以排序一个具有15个元素的数组为例,其调用堆栈为:
我们单独将Merge步骤拿出来,可以看到合并的过程如下:
三 图示及动画
如果以排序38,27,43,3,9,82,10为例,将合并排序画出来的话,可以看到如下图:
下图是合并排序的可视化效果图:
对6 5 3 1 8 7 24 进行合并排序的动画效果如下:
下图演示了合并排序在不同的情况下的效率:
1. 合并排序的平均时间复杂度为O(nlgn)
证明:合并排序是目前我们遇到的第一个时间复杂度不为n2的时间复杂度为nlgn(这里lgn代表log2n)的排序算法,下面给出对合并排序的时间复杂度分析的证明:
假设D(N)为对整个序列进行合并排序所用的时间,那么一个合并排序又可以二分为两个D(N/2)进行排序,再加上与N相关的比较和计算中间数所用的时间。整个合并排序可以用如下递归式表示:
D(N)=2D(N/2)+N,N&1;
D(N)=0,N=1; (当N=1时,数组只有1个元素,已排好序,时间为0)
因为在分治算法中经常会用到递归式,所以在中有一章专门讲解递归式的求解和证明,使用可以直接求解出该递归式的值,后面我会简单介绍。这里简单的列举两种证明该递归式时间复杂度为O(nlgn)的方法:
Prof1:处于方便性考虑,我们假设数组N为2的整数幂,这样根据递归式我们可以画出一棵树:
可以看到我们对数组N进行MergeSort的时候,是逐级划分的,这样就形成了一个,树的每一及子节点都为N,树的深度即为层数lgN+1,满二叉树的深度的计算可以查阅相关资料,上图中最后一层子节点没有画出来。这样,这棵树有lgN+1层,每一层有N个节点,所以
&&&&&&&&&&&&&&&&&&&&&&&&&&&& D(N)=(lgN+1)N=NlgN+N=NlgN
Prof2:我们在为递归表达式求解的时候,还有一种常用的方法就是数学归纳法,
首先根据我们的递归表达式的初始值以及观察,我们猜想D(N)=NlgN.
当N=1 时,D(1)=0,满足初始条件。
为便于推导,假设N是2的整数次幂N=2k, 即D(2k)=2klg2k = k*2k
在N+1 的情况下D(N+1)=D(2k+1)=2k+1lg2k+1=(k+1) * 2k+1,所以假设成立,D(N)=NlgN.
2. 合并排序需要额外的长度为N的辅助空间来完成排序
如果对长度为N的序列进行排序需要&=clogN 的额外空间,认为就是(in place排序)也就是完成该排序操作需要较小的,固定数量的额外辅助内存空间。之前学习过的选择排序,插入排序,希尔排序都是原地排序。
但是在合并排序中,我们要创建一个大小为N的辅助排序数组来存放初始的数组或者存放合并好的数组,所以需要长度为N的额外辅助空间。当然也有前人已经将合并排序改造为了,但是算法的实现变得比较复杂。
需要额外N的空间来辅助排序是合并排序的最大缺点,如果在内存比较关心的环境中可能需要采用其他算法。
五 几点改进
对合并排序进行一些改进可以提高合并排序的效率。
1. 当划分到较小的子序列时,通常可以使用插入排序替代合并排序
对于较小的子序列(通常序列元素个数为7个左右),我们就可以采用插入排序直接进行排序而不用继续递归了),算法改造如下:
private const int CUTOFF = 7;//采用插入排序的阈值
private static void Sort(T[] array, int lo, int hi)
if (lo &= hi) return; //如果下标大于上标,则返回
if (hi &= lo + CUTOFF - 1) Sort&T&.SelectionSort(array, lo, hi);
int mid = lo + (hi - lo) / 2;//平分数组
Sort(array, lo, mid);//循环对左侧元素排序
Sort(array, mid + 1, hi);//循环对右侧元素排序
Merge(array, lo, mid, hi);//对左右排好的序列进行合并
2. 如果已经排好序了就不用合并了
当已排好序的左侧的序列的最大值&=右侧序列的最小值的时候,表示整个序列已经排好序了。
算法改动如下:
private static void Sort(T[] array, int lo, int hi)
if (lo &= hi) return; //如果下标大于上标,则返回
if (hi &= lo + CUTOFF - 1) Sort&T&.SelectionSort(array, lo, hi);
int mid = lo + (hi - lo) / 2;//平分数组
Sort(array, lo, mid);//循环对左侧元素排序
Sort(array, mid + 1, hi);//循环对右侧元素排序
if (array[mid].CompareTo(array[mid + 1]) &= 0) return;
Merge(array, lo, mid, hi);//对左右排好的序列进行合并
分治算法通常比较容易进行并行化,在这篇文章中已经展示了如何对快速排序进行并行化(快速排序在下一篇文章中讲解),合并排序一样,因为我们均分的左右两侧的序列是独立的,所以可以进行并行,值得注意的是,并行化也有一个阈值,当序列长度小于某个阈值的时候,停止并行化能够提高效率,这些详细的讨论在这篇文章中有详细的介绍了,这里不再赘述。
合并排序和快速排序一样都是时间复杂度为nlgn的算法,但是和快速排序相比,合并排序是一种稳定性排序,也就是说排序关键字相等的两个元素在整个序列排序的前后,相对位置不会发生变化,这一特性使得合并排序是稳定性排序中效率最高的一个。在Java中对引用对象进行排序,Perl、C++、Python的稳定性排序的内部实现中,都是使用的合并排序。
本文介绍了分治算法中比较典型的一个合并排序算法,这也是我们遇到的第一个时间复杂度为nlgn的排序算法,并简要对算法的复杂度进行的分析,希望本文对您理解合并排序有所帮助,下文将介绍快速排序算法。
阅读(...) 评论()

我要回帖

更多关于 区域合并算法 matlab 的文章

 

随机推荐