前面讲的尚未涉及到排序算法的核心部分。即有没有办法改进合并算法呢? web
合并两个排号序列须要额外的等长空间。若是不额外申请空间,就只能用O(n2)至O(nlogn)的方法代替。可是这个问题真的就有那么难吗? 算法
事实上这是一系列看似十分简单但真要解决起来难死无数人的问题之一。 spa
改进算法该从哪一个方向着手? 设计
先来看一下,全部的计算机算法,均可以用五个维度来衡量质量,他们是: 排序
基本上,能够下降一个方向上的标准来得到其余四项方面的提高。那些普遍流传,使用广泛的算法无不是在各个方面都取得了较为完美的平衡。有些算法在某几个维度上比较极端,适合用来处理特殊状况。而剩下的其余算法基本上不具备实用价值。 开发
在通常工程上算法的设计,其实就是在平衡这五个项目,这里面包含了平时工做中用到的全部指导原则: get
空间:若是容许使用额外的空间,经常能把时间复杂度降到比n更低,甚至1,好比查表法,基数排序法等。 it
时间:若是空间使用受限,就极可能要接受时间上提升复杂度,最终可能得不偿失。好比尝试解决合并有序数列不额外耗费空间的问题. pdf
基本上算法复杂度 = 空间复杂度x时间复杂度 搜索
稳定度:若是愿意牺牲算法的稳定度,或许可以在时间和空间上得到巨大的利益,好比快排就是用不稳定算法替换掉了O(N)的空间消耗,从而成为目前排序算法中的王者。
精确度:通常咱们都要求计算机的运算结果100%精确,但若是容许计算结果哪怕牺牲掉一丁点儿的精确度,就能期待在空间和时间上得到极大的提高。下降精确度,在不要求得到真正精确的数据的场合特别有用,好比web搜索,近年来因为云服务,云数据的概念炒热,相关的算法也逐渐进入你们的视野。不过容许非100%精确度的使用场合仍是很是之少的。
数据特殊性:有一些比O(nlogn)更低的排序算法被开发出来,但都是基于特定的数据类型,或知足特定条件的数据集合等。在平常工做中,这是个颇有用的技巧,由于绝大部分时候咱们都只须要处理特定的数据类型和数据集合,所以,选择应付特殊性的算法能够节省大量的时间空间成本,好比前一篇文章中,将求最高位数的问题,转成求最高位的奇偶性的问题,问题的解法直接从O(n)降到O(1)。
再来看咱们想要改进的算法,精确度确定是不能损失,泛用的算法数据也不能有特殊性,在算法复杂度不会低于O(NlogN)的状况下,突破的方向看来就只剩降低低稳定度一条路可走了——而这正是快速排序作的事——用一个不稳定可是十分绝妙的交换顺序算法代替了O(n)的空间消耗,从而摘走了排序算法的桂冠,甚至还成为了上世纪最伟大的计算机算法之一。想象一下,一个耗费O(n)空间的快排算法其实还不如归并算法。
因此归并算法想要有所突破,就须要像快速排序那样找个替换空间的不稳定算法出来,若是能找到的话,至少能和快排势均力敌吧。
结果,还真有人宣称找到了改进的方法:http://akira.ruc.dk/~keld/teaching/algoritmedesign_f04/Artikler/04/Huang88.pdf
在这个连接的论文里,做者宣称找到了合并有序数列,在线性时间,不耗费额外的On空间,可是不稳定的算法。这个算法知道的人很少,但看样子是至关复杂吧,就算是On的算法,实施起来过于麻烦的话,大概你们仍是去用快排算法了。