冒泡排序

交换排序

设序列为【9,8,7,6,5,4,3,2,1】,希望由小到大排列

流程:

  • 从前往后,或从后往前,两两比较相邻元素的值,若出现逆序,则交换他们
  • 下一趟冒泡,已有一个元素确定最终位置,待处理序列规模减1,依次类推
  • 同时为了减少无逆序情况下的循环次数,设置一个标记位,如果第一趟两两对比无交换产生,说明序列有序,直接跳出循环

运行结果:我习惯从后往前,称之为沉塘法

交换排序

知识点:

  • 最坏情况下(完全逆序),对比的次数为,1+2...+(n-1) = n(n-1)/2
  • 最坏情况下(完全逆序),对比的次数为,1*3+2*3...+(n-1)*3 = 3n(n-1)/2
  • 冒泡排序是稳定排序
  • 冒泡排序的空间复杂度为o(1),最坏时间复杂度为o(n2)

快速排序

流程:

给定原始数列如下,要求从小到大排序:

交换排序

首先,我们选定基准元素Pivot,并且设置两个指针left和right,指向数列的最左和最右两个元素:

交换排序

接下来,从right指针开始,把指针所指向的元素和基准元素做比较。如果比Pivot大,则right指针向左移动;如果比Pivot小,则把right所指向的元素填入坑中。

在当前数列中,1<4,所以把1填入基准元素所在位置,也就是坑的位置。这时候,元素1本来所在的位置成为了新的坑。同时,left向右移动一位。

交换排序

此时,left左边绿色的区域代表着小于基准元素的区域

接下来,我们切换到left指针进行比较。如果left指向的元素小于Pivot,则left指针向右移动;如果元素大于Pivot,则把left指向的元素填入坑中。

在当前数列中,7>4,所以把7填入index的位置。这时候元素7本来的位置成为了新的坑。同时,right向左移动一位。

交换排序

此时,right右边橙色的区域代表着大于基准元素的区域

下面按照刚才的思路继续排序:

8>4,元素位置不变,right左移。

交换排序

2<4,用2来填坑,left右移,切换到left。

交换排序

6>4,用6来填坑,right左移,切换到right。

交换排序

3<4,用3来填坑,left右移,切换到left。

交换排序

5>4,用5来填坑,right右移。这时候left和right重合在了同一位置。

交换排序

这时候,把之前的Pivot元素,也就是4放到index的位置。此时数列左边的元素都小于4,数列右边的元素都大于4,这一轮交换终告结束。

交换排序

一轮的运行结果,运气好直接一轮有序,事实上一轮只是把大于基准者置右,小于基准者置左,接下来仍需递归地对左右半部分进行快速排序:

交换排序

知识点:

  • 由于是递归调用,快速排序的空间复杂度主要取决于栈的深度,而栈的深度取决于基准是否选的好,运气好的话,每一次选择的基准都能把待处理序列二等分,则栈的深度=完全二叉树的深度=log2(n+1);运气不好,每一次选择的基准都是把剩下的部分挪到另外一遍,这样需要递归n-1次,栈深度=n-1
  • 平均空间复杂度为o(log2n),最坏为o(n)
  • 不稳定
  • 平均时间复杂度是o(nlog2n)

相关文章:

  • 2021-10-18
  • 2021-12-27
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-11-21
  • 2021-08-08
猜你喜欢
  • 2021-09-12
  • 2021-06-23
  • 2021-12-29
相关资源
相似解决方案