常见的排序算法的比较

当前的排序算法,主要是在时间复杂度和稳定性上面进行比较,一下是常见的7中算法是之间复杂度和稳定性情况对比



我们来站在逆序数的角度来分析不同的排序算法之间的时间复杂度问题。

如果我们想把一个长度为n的数组元素按升序进行排序,那么如果一个元素a[i]比a[j]大(i<j)那么就称a[i]和a[j]为一个逆序

而我们的排序算法就是要把一串数的逆序数变为零。

再说说这个时间复杂度的问题,常见的时间复杂度O(nlogn),是怎么来的呢。


如果一个待排序的序列只包含3个数,记为k1,k2,k3

那么,这三个数可能 的情况,一共有6种,3!=6

上述图中,数的叶子节点的个数就是6.

推广,含有n个记录进行排序,有n!个不同的结果。我们已经知道,若树的高度为h,那么树的叶子节点最多维2^h-1个。n!个叶子节点需要o(log(n!))

由此得出结论,任何一个借助比较进行排序的算法,在最坏的情况下所需进行比较的次数为log(n!),根据斯特林公式,o(log(n!))=o(nlogn).

我们来看看最简单的冒泡排序算法


冒泡排序法,是将n个记录进行比较,得到最大的记录沉底。一共需要比较n-1+n-2+...+1=n*(n-1)/2.时间复杂度为o(n2)

站在逆序数的角度来看,由于每次只是将相邻的两个数进行交换,也就是只改变了一次逆序,所以时间复杂度很高。

但是这种算法是稳定的,因为每次只交换相邻的两个数,所以是稳定法的算法

下面再来看选择排序法


这是选择排序算法的截图,首先选择排序算法是不稳定的,证明一个算法不稳定,只需要给一个反例就行了

假如有这样一个例子,{5,5,2,6,8},根据选择排序算法,首先选出最小的记录2,然后将2和第一个数进行交换,那么得到的序列为{2,5,5,6,8}

两个5的相对位置变了,所以这种算法不稳定。

从理论上也可以证明选择排序算法不稳定,因为待交换的两个数不一定相邻,那么这个算法就是不稳定的。

选择排序算法跟冒泡排序算法一样, 时间复杂度都为o(n2)


插入法排序有一个很形象的例子就是,打纸牌,我们打纸牌的时候,一般都是排好序了的,当再摸一张新牌的时候,我们会将这张牌放入已排序好的牌中

这就是所谓的插入排序

插入排序的思想就是从记录的尾部向前进行遍历,若待插入的记录小于a[i]同时大于a[j](i>j)那个就讲这个记录插入

当一个序列是逆序的时候,那么插入法排序的时间复杂度为o(n2),这是最差的情况,当序列为顺序的时候,那么就不需要插入,直接进行比较即可,这时的

时间复杂度为o(n)

查入排序是稳定的排序算法,因为他只对相邻的记录进行比较和交换

插入排序的改进排序算法是希尔排序

由于简单插入排序只将相邻的记录进行比较和交换,一一次只能改变一个逆序数,对于有的序列,这种算法的效率是很低的

那么,就提出了一种改进排序算法,希尔排序

简单插入排序只是将相邻记录进行比较,那么希尔排序就是将不相邻的记录进行比较

它的思路就是将一个序列以一定的步长进行分割,分割为不同的序列i1,i2,i3,...,再讲这些序列进行排序,再讲排完序的序列进行合并

由于不是对相邻的记录进行比较和交换,这种算法的效率很高,时间复杂度很低

但是,这是一种不稳定的算法。

下面来看看归并排序算法


归并排序是一种分治算法的思想进行排序的

分治,分而治之,将一个序列分散成若干个序列,将这若干个序列进行排序,然后合并,进行一次排序

归并排序的一种时间复杂度很低并且是一种稳定的算法

为什么归并排序是时间复杂度是o(nlogn)呢,因为归并排序是利用树的思想将记录分布在树的节点上。

最后一种是快速排序算法


快速排序是思想是取一个序列中的一个元素,然后将整个序列中小于这个元素的记录分布在该元素的左边

大于这个元素的记录分布在这个元素的右边

同样的道理,由于快速排序进行的不是相邻元素之间的比较,那么这种算法是不稳定的

但是时间复杂度低

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值