经典排序算法复习及笔记(包括讲解排序算法稳定性,快排为例)(面试必问)

https://www.cnblogs.com/onepixel/p/7674659.html - 十大经典排序算法(动图演示)

6、快速排序(Quick Sort)

快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

6.1 算法描述

相关概念

  • 稳定如果a原本在b前面,而a=b,排序之后a仍然在b的前面。
  • 不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。
  • 时间复杂度:对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。
  • 空间复杂度:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模n的函数。 

问:为什么比较排序算法中,排序算法插入、归并、冒泡排序是稳定的,而其他排序是不稳定的?

插入:是不断地向后缩小序列,然后选择后面的最小的放到前面,而插入的位置向后放置。这里就保证了前一个元素不会跑到后一个元素后面。

冒泡:是采取整体的策略,它从头到末尾把最大的元素像气泡那样放置到最后,在期间是比较前一个元素和后一个元素,如果前一个元素大于后面元素则交换,等于或小於则不交换,这就导致小或等的前一个绝不能来到后面。·

归并:归并采取分治法:先把列划分位几个局部,通过在它们之前排序。而归并中采用2路归并,就是两个子序列比较,如果前一个序列当前元素小于或等于后一个序列当前元素,放进排序列表,当前子序列索引index1++。后一个大于前一个放进排序列表,当前子序列缩影index2++。并没有把相等的元素交换到位置。

而其他不稳定的排序算法,为什么不稳定,说到底,就是在排序的过程中,并没有做好:加入前一个元素小于后一个元素,在排序的过程中把前一个放到了后面。这经常见于排序算法中比较大小时使用了swap的函数,交换位置。

而问不稳定的常见于快排。

快排算法如下:

快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下:

  • 从数列中挑出一个元素,称为 “基准”(pivot);(一般是挑首个元素作为基准)
  • 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;(其实就是通过index索引,当确定基准后,通过索引index=基准+1,遍历比较在这个子串的元素,当比基准小,交换索引和该元素。索引index++)
  • 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

快排不稳定原因:快排因为排序是通过基准,索引、和序列范围。通过递归的方式进行排序,而比较则是比较基准和当前索引及以后的元素,比当前基准的元素小,则把当前索引(当前及前面比基准元素小,后为大)和后面比基准小的元素位置做交换。假如组后索引和基准位置做交换,而前索引前为arr(基准=3),a=2,b=2,用了swap函数,交换arr和b,则成了b,a,arr.位置则交换了。所以不是稳定算法。

堆:他的增删改查的最好和最坏情况的在排序二叉树上操作,都是有约束的,所以是不稳定的。(这里更正一下,堆排序的过程中,相等元素是怎么排序的???后序再更)

 

最好最坏时间复杂度都不变的是:

堆:(无需多言,凡是使用树做排序的时间复杂度都是一样的)

插入排序:无论如何都要从头都搜索,缩小一个个字符串搜索。

选择,和堆相似,都是无论如何都要从头都搜索,缩小一个个字符串搜索。但不同的是选择插入使用的是插入该位置,位置后面的元素向后放置,而选择是直接交换插入元素位置和选择位置元素的位置。

再说时间负责度O(n2)和O(nlog2n)

凡是线性和整体排序的都是O(n2),而使用树结构或分治算法从局部都整体的都是O(nlog2n).注意希尔排序虽然也划分不同的序列,但非常注重整体。只不过是把划分序列而已,而在序列中排序的算法依然是直接插入排序。但为什么算法复杂度最好最坏不同呢?其实加入在最好的情况下回采用局部序列前后端比较如果刚好小于就不用排序。但是归并也采用局部却是最好最坏都一样,是因为两个子序列归并的时候采用二路归算法,每一个元素都要遍历比较~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章