数据结构排序笔记

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011975363/article/details/87901197

快速排序

  • 填坑法,初始时,选取一个关键数将它的位置空出来,用i指向它,用j指向待排序数列的最后一个数,如果j指向的数小于关键数,则将这个数填入关键字对应的位置,j保持不动,然后i向前移动,当i遇到比关键字大的数时,将该数填入j所在的位置,i保持不动,然后j后退,遇到比关键字小的数时停止,直到i,j相遇,然后把关键字放入i对应的位置,一次排序完成。关键字左右两边使用同样的方法进行排序。
  • 最坏的情况:基本有序,退化为冒泡排序,几乎要比较n*n次

插入排序

  • 将当前数据插入到前部分有序数列中,从第二个数开始排序。
  • 顺序插入排序,二分法插入排序。
  • 最好的情况:基本有序,最坏的情况:逆序。

希尔排序

  • 将长度为n 的数列,依次按不同的增量进行分组比如(n/2,n/4,…1)每一次,每一组都采用插入排序的方法进行排序。比如长度为10的数列a,第一次排序,增量d=5,所以a分为,a[1]与a[6],a[2]与a[7],a[3]与a[8],a[4]与a[9],a[5]与a[10]五组,每组采用插入排序进行排序,第二次排序,d=2,则,a[1,3,5,7,9],a[2,4,6,8,10]各自为一组,采用插入排序进行排序,第三次,d=1,只有一组,采用插入排序,得到最终结果。
  • 优点:减少数据移动的次数
  • 最坏情况和平均情况差不多

选择排序

  • 每次从未排序的数列中选出最小/最大的放在该无序数列的前面。

堆排序

  • 将数列写成二叉树的形式,调整二叉树,使得根节点为最大值或者最小值,使得每棵子树都满足根节点大于或小于孩子节点
  • 关键:调整堆,使得整个二叉树为大根堆,将根节点与最后一个叶子节点互换,确定根节点对应的数的位置,然后对除最后一个叶子节点以外的数列重复上述步骤,直到数列的长度为2.

冒泡排序

  • 数列从左往右或从右往左,相邻的数相互比较,将大的数向右移,小的数向左移,每次从待排序数列中找到最大值,并将它移到数列的末尾,直到数列长度为2。
  • 最好情况:正序有序,最坏情况:逆序有序

归并排序

  • 将两个有序的数组合并成为一个有序数组放于第三个数组中,先比较两个数组中的第一个数,谁小就将谁先放入第三个数组中,将小的那个数所在的数列的第二个数继续与之前那数比较,依旧谁小,谁进入第三个数组,直到某一个组全部进入第三个数组,然后另一个数组中剩余的数,无需在排序,直接按顺序放入第三个数组中。
  • 怎样得到有序的数组:第一次进行分组时,使得每个组中只有一个元素,这样初始时所有组都是有序的,然后两个元组,四个元素…一组进行合并,直到数列只包含一组,则合并成功,完成排序。

基数排序

  • LSD:十个桶,从数据的最低位到最高位进行排序,先对个位进行排序,然后对十位进行排序。。
  • MSD:从数据的最高位开始排序,假如一个3位数,先对百位由小到大进行排序,然后对每个百位中对应的数,分别对十位进行排序,在对每个十位对应的数,根据个位的大小进行排序。

总结:排序算法分为三类

  • 交换排序:快速排序,冒泡排序

  • 插入排序:直接插入排序,归并排序,希尔排序(组内进行直接插入排序)

  • 选择排序:直接选择排序,堆排序

  • 插入排序,直接将当前数据插入前面的有序的数据中,选择排序,从待排序的数据中选择选择最小/最大的数,一个跟有序数列比,一个在无序数列中选择。

  • 不稳定排序:快速排序,希尔排序,直接选择排序,堆排序

  • 稳定排序:冒泡排序,直接插入排序,归并排序,基数排序

  • 快速排序的空间复杂度次高,归并排序O(N),基数排序

空间复杂度

  • 定长空间:与程序输入,输出无关的空间,指令空间(存储代码空间),单变量的存储空间,定长结构变量的存储空间,常量存储空间。我认为是程序中定义的变量所占的空间,定义的变量数越多,则占的空间越大。
  • 变长空间:与程序输入,输出有关的空间,如果是递归,还应加上递归时所需的工作空间,即调用函数时需要输入,输出的变量个数,长度或取值。

猜你喜欢

转载自blog.csdn.net/u011975363/article/details/87901197