多种排序算法整理

最近面试一直问到排序,老是各种搞混,特地来整理整理

先盗用一张图:

说明: 内部排序基于内存,外部排序是数据量大,而内存与外存的相结合的排序

一、插入排序

  关键词:插入,将数字插入到一条已经排好序的有序表中。

1.1直接插入排序

  假设要5,4,2,3,1 要升序排列。

  i=1  5

  i=2  5,4    ==>4,5

  i=3  4,5,2  ===>2,4,5

  i=4  2,4,5,3  ==>2,3,4,5

  ...

  思想很简单,就是从一个元素开始,一个个元素添加,返回有序列表。

  其复杂度为   1+2+3+。。+n = O(n2)

1.2希尔排序

  希尔排序是直接排序的一个加强版,我们知道直接排序前,要排序的序列有一定的序列特性,则需要移动的次数减少,效率提高。

  如,要排序的序列为5,4,3,2,1 与序列 1,2,5,4,3,相比,运用直接排序,后者将移动较小的次数。

  希尔排序的基本思想是:

  把记录按步长 gap 分组,对每组记录采用直接插入排序方法进行排序。
  随着步长逐渐减小,所分成的组包含的记录越来越多,当步长的值减小到 1 时,整个数据合成为一组,构成一组有序记录,则完成排序。

  我们来通过演示图,更深入的理解一下这个过程。 

 

  希尔排序是一种不稳定的排序:其平均复杂度为 O(Nlog2N)

  具体大家可以参考:http://www.cnblogs.com/jingmoxukong/p/4303279.html

二、选择排序

  关键词:选择,选择最小的与第一个交换,剩下的最小与第二个交换,一次类推

2.1简单选择排序

  选择最小的与第一个交换,剩下的最小与第二个交换,。。。。

  

  比较稳定的排序,时间复杂度为:n+(n-1)+..+1 = O(n2)

2.2堆排序

 

堆的定义如下:具有n个元素的序列(k1,k2,...,kn),当且仅当满足

时称之为堆。由堆的定义可以看出,堆顶元素(即第一个元素)必为最小项(小顶堆)。
若以一维数组存储一个堆,则堆对应一棵完全二叉树,且所有非叶结点的值均不大于(或不小于)其子女的值,根结点(堆顶元素)的值是最小(或最大)的。如:

(a)大顶堆序列:(96, 83,27,38,11,09)

  (b)  小顶堆序列:(12,36,24,85,47,30,53,91)

  可以看出堆排序本质也是选择排序,以最小堆为例,堆顶元素为最小值,输出最小值,并将最后一个元素提至堆顶(蓄意破坏堆结构),则重新构建最小堆后,堆顶又是最小值,以此内推。

  堆排序也是一种不稳定的排序,其在最坏的情况下复杂度为O(nlogn)

三、交换排序

  关键词:交换

  

3.1冒泡排序

  形象理解:大的往下沉,通过对比交换

  

   其复杂度为:(n-1)+(n-2)+。。。+1 = O(n2

  

3.2快速排序

  形象理解:选择一个基数,大于它的在右边,小于它的在左边。通过动态规划,自底向上,即完成了排序

(a)一趟排序的过程:

(b)排序的全过程

  可以看出快速排序是不稳定的算法,其算法平均复杂度为O(nlog2n)

四、归并排序(Merge Sort)

  1成2,2成4,4成8

  

  归并排序的最好、最坏和平均时间复杂度都是O(nlogn)

五、桶排序

例如要对大小为[1..1000]范围内的n个整数A[1..n]排序  

 首先,可以把桶设为大小为10的范围,具体而言,设集合B[1]存储[1..10]的整数,集合B[2]存储   (10..20]的整数,……集合B[i]存储(   (i-1)*10,   i*10]的整数,i   =   1,2,..100。总共有  100个桶。  

  然后,对A[1..n]从头到尾扫描一遍,把每个A[i]放入对应的桶B[j]中。  再对这100个桶中每个桶里的数字排序,这时可用冒泡,选择,乃至快排,一般来说任  何排序法都可以。

  最后,依次输出每个桶里面的数字,且每个桶中的数字从小到大输出,这  样就得到所有数字排好序的一个序列了。  

  假设有n个数字,有m个桶,如果数字是平均分布的,则每个桶里面平均有n/m个数字。如果  

  对每个桶中的数字采用快速排序,那么整个算法的复杂度是  

  O(n   +   m   *   n/m*log(n/m))   =   O(n   +   nlogn   -   nlogm)  

  从上式看出,当m接近n的时候,桶排序复杂度接近O(n)  

  当然,以上复杂度的计算是基于输入的n个数字是平均分布这个假设的。这个假设是很强的  ,实际应用中效果并没有这么好。如果所有的数字都落在同一个桶中,那就退化成一般的排序了。  

        前面说的几大排序算法 ,大部分时间复杂度都是O(n2),也有部分排序算法时间复杂度是O(nlogn)。而桶式排序却能实现O(n)的时间复杂度。但桶排序的缺点是:

        1)首先是空间复杂度比较高,需要的额外开销大。排序有两个数组的空间开销,一个存放待排序数组,一个就是所谓的桶,比如待排序值是从0到m-1,那就需要m个桶,这个桶数组就要至少m个空间。

        2)其次待排序的元素都要在一定的范围内等等。

       桶式排序是一种分配排序。分配排序的特定是不需要进行关键码的比较,但前提是要知道待排序列的一些具体情况。

参考:http://blog.csdn.net/hguisu/article/details/7776068

原文地址:https://www.cnblogs.com/yanyouqiang/p/6754227.html