六种常见的排序算法

一.冒泡排序

        冒泡排序就是重复“从序列右边开始比较相邻两个数字的大小,再根据结果交换两个数字 的位置”这一操作的算法。在这个过程中,数字会像泡泡一样,慢慢从右往左“浮”到序列的 顶端,所以这个算法才被称为“冒泡排序”。

在冒泡排序中,第 1 轮需要比较 n -1 次,第 2 轮需要比较 n -2 次……第 n -1 轮需 要比较 1 次。因此,总的比较次数为 (n -1) +(n -2) +…+1 ≈ n2 /2。这个比较次数恒定为 该数值,和输入数据的排列顺序无关。

冒泡排序的时间复杂度为 O(n2 )。

二.选择排序

        选择排序就是重复“从待排序的数据中寻找最小值,将其与序列最左边的数字进行交换” 这一操作的算法。在序列中寻找最小值时使用的是线性查找。

选择排序的时间复杂度也和冒泡排序的一样,都为 O(n2 )。

三.插入排序

        插入排序是一种从序列左端开始依次对数据进行排序的算法。在排序过程中,左侧的数据 陆续归位,而右侧留下的就是还未被排序的数据。插入排序的思路就是从右侧的未排序区域内 取出一个数据,然后将它插入到已排序区域内合适的位置上

以时间复杂度和冒泡排序的一样,都为 O(n2 )。

1.首先,我们假设最左边的数字5已经完成排序,所以此时只有5是已归位的数字。

2.接下来,从待排数字(未排序区域)中取出最左边的数字 3,将它与左边已归位的数字进行比较。若左 边的数字更大,就交换这两个数字。重复该操作,直到左边已归位的数字比取出的数字更小,或者取 出的数字已经被移到整个序列的最左边为止。由于5>3,所以交换这两个数字。

 3.对数字3的操作到此结束。此时3和5已归位,还剩下右边7个数字尚未排序。

 4.重复上述操作,直到所有数字都归位。

四.堆排序

        堆排序的特点是利用了数据结构中的堆。

        堆排序一开始需要将 n 个数据存进堆里,所需时间为 O(nlogn)。排序过程中,堆从 空堆的状态开始,逐渐被数据填满。由于堆的高度小于 log2n,所以插入 1 个数据所需要 的时间为 O(logn)。

        每轮取出最大的数据并重构堆所需要的时间为 O(logn)。由于总共有 n 轮,所以重 构后排序的时间也是 O(nlogn)。因此,整体来看堆排序的时间复杂度为 O(nlogn)。

         这样来看,堆排序的运行时间比之前讲到的冒泡排序、选择排序、插入排序的时间 O(n2 ) 都要短,但由于要使用堆这个相对复杂的数据结构,所以实现起来也较为困难。

1.首先,在堆中存储所有的数据,并按降序来构建堆。

 2.现在,所有数据都存进堆里了。为了排序,需要再从堆中把数据一个个取出来。

3.从降序排列的堆中取出数据时会从最大的数据开始取,所以将取出的数据反序输出,排序就完成了。首先取出根结点的数字7。

 4.重新构造堆。

5.同样地,取出根结点的数字6,将它放在右数 第2个位置上。

6.重复上述操作直到堆变空为止,从堆中取出了所有数字,排序完成。

五.归并排序

        归并排序算法会把序列分成长度相同的两个子序列,当无法继续往下分时(也就是每个子 序列中只有一个数据时),就对子序列进行归并。归并指的是把两个排好序的子序列合并成一个 有序序列。该操作会一直重复执行,直到所有子序列都归并为一个整体为止。总的运行时间为 O(nlogn),这与前面讲到的堆排序相同。

1首先,要把序列对半分割,先分成两段,再继续往下分,分割完毕。

 

2接下来对分割后的元素进行合并,合并时需要将数字按从 小到大的顺序排列。把6和4合并,合并后的顺序为[4, 6]。接下来把3和7合并,合并后的顺序为[3, 7]。

 

3 此时要比较 两个子序列 的首位数字 4 和 3。下面,我们来看看合并 [4, 6]和[3, 7]。合并这种含 有多个数字的子序列时,要先比较首位数字,再移动较小的数字。

4递归执行上面的操作,直到所有的数字都合为 一个整体为止。这里也要比较两个子序列中的 首位数字。合并完成,序列的排序也就完成了。

 

 

六.快速排序

        1快速排序算法首先会在序列中随机选择一个基准值(pivot),然后将除了基准值以外的数分 为“比基准值小的数”和“比基准值大的数”这两个类别,再将其排列成以下形式。

 

        2接着,对两个“[ ]”中的数据进行排序之后,整体的排序便完成了。对“[ ]”里面的数据 进行排序时同样也会使用快速排序。分别对左边和右边的数据进行排序后,就能完 成整体的排序。

 

         3首先来看看 如何对右边的数据进行排序吧。随机选择一个基准值。这次选择6。把其余数据分别和基准值6进行比较,小于基 准值的就往左移,大于的就往右移。完成了大小比较和位置移动。

        4和前面一样,对左右两边分别进行排序,进而完成整体排序。但是此时左边只有 5,所以已经是排序完 成的状态,不需要任何操作。而右边就和前面一样,先选出基准值。选择8作为基准值。将9和7分别与基准值8进行比较后,两个数字 的位置便分好了。8的两边都只有一个数据,因 此不需要任何操作。这样7、8、9便完成排序了。

 

         5回到上一行,由于7、8、9完成了排序,所以 5、6、7、8、9也完成了排序。于是,最初选择的基准值4的右边排序完毕。

        6左边也以相同的操作进行排序,整体的排序工作也就完成了。

 

 

         总结:快速排序是一种“分治法”。它将原本的问题分成两个子问题(比基准值小的数和 比基准值大的数),然后再分别解决这两个问题。子问题,也就是子序列完成排序后,再 像一开始说明的那样,把他们合并成一个序列,那么对原始序列的排序也就完成了。 不过,解决子问题的时候会再次使用快速排序,甚至在这个快速排序里仍然要使用 快速排序。只有在子问题里只剩一个数字的时候,排序才算完成。 像这样,在算法内部继续使用该算法的现象被称为“递归”。

 

  • 6
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值