数据结构中的排序

来源:互联网 发布:无网络手机电脑传文件 编辑:程序博客网 时间:2024/05/18 02:11

最近看到排序,同样记录一下以便以后回忆,用自己最通俗易懂的语言写出来,就是为了一看到脑子里面就能回忆起来。

首先这里面的排序只考虑内部排序,即在内存中的排序。主要有:

1)插入排序。

这里就不分什么直接插入,折半插入之类的。就是一堆元素,插入到已经排好序的另一堆元素里面(可以只有一个),当然少不了的就是比较了,不过java里面有Comparable的compareTo()方法也是比较简单。

效率:好的情况就是初始的这一堆元素已经排好序了,插入的时候与前一个元素比较一次即可,时间复杂度为O(N)。最坏当然就是反过来了,为O(N^2)。

2)希尔排序。

找一个“间隔”,从元素数组中距离间隔的元素进行插入排序,最后记过几次间隔排序后,元素基本有序,再对全部元素进行一次插入排序。问题就是“间隔”的选取。比较流行的一个选择是使用Shell建议的序列:h=[N/2](向下取整)。注意的是增量序列里的值没有除1之外的公因子,并且最后一个增量值必须是1 。

效率:它的效率分析是个长期问题,使用Shell增量最坏为Θ(N^2)。使用Hibbard增量时最坏情形为Θ(N^(3/2))。

3)堆排序。

就是优先队列的思想,先对N个元素建立一个二叉堆,花费O(N),然后执行N此deleteMin操作,按照顺序最小的元素先离开,将这些元素记录到一个数组里面,最后拷贝回来,得到结果,每个deleteMin花费时间O(logN),总时间为O(N logN),只要搞清楚优先队列即可。问题是如何避免使用第二个数组,一种方法是根上删除的最小元素放到堆最后的单元,这个元素不记为原来堆大小,原来堆缩小1个,依次这样下去。

效率:如上都是O(N logN)。

   对N个互异项的随即排列进行堆排序所有的比较的平均次数为2 N log N -O(N log log N)。(证明看看。)

4)归并排序。

它是用于分析递归的经典实例,操作是将2个已排序的表合成一个。具体点就是一堆元素数组,递归地将前半部分数据和后半部分数据各自归并排序,得到排序后的两部分,使用合并算法合并到一起,合并2个已排序的表时间是线性的,因最多进行N-1次。这是经典的分治策略,分成小问题递归,然后再合起来。

效率:都是O(N logN)。但是与其他的O(N logN)排序不同的是,它的运行时间严重依赖于比较元素和在数组中移动元素的相对开销,这种开销和语言也是有关的(具体就要涉及java和C++的泛型程序中的不同了)

5)快速排序

这个太常见了,选个轴元P(不要选第一个元素),然后,选个i,选个j,当i在j的左边时,i右移,移过那些<P的元素,并将j左移,移过那些>P的元素。当i和j停止时,i指向一个大元素,j指向一个小元素,,如果i在j的左边,互换。重复过程直到i和j彼此交错,最后一步是将P与i指向的交换即可。快排也是递归的。

PS:这里有个问题就是处理相等元素。

效率:最差的时候,取第一个为轴元,然后元素数组基本有序时,为O(N^2),平均为O(N log N)。

最后:任何只用到比较的排序算法在最坏情况下都需要Ω(N logN)。

0 0
原创粉丝点击