插入排序
步骤:
- 从第一个元素开始,该元素可以认为已经被排序
- 取出下一个元素,在已经排序的元素序列中从后向前扫描
- 如果该元素(已排序)大于新元素,将该元素移到下一位置
- 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
- 将新元素插入到该位置中
- 重复步骤2
稳定
空间复杂度O(1)
时间复杂度O(n2)
最差情况:反序,需要移动n*(n-1)/2个元素
最好情况:正序,不需要移动元素
在列表已被排序时,插入排序是线性算法O(n)。
在列表“近似排序”时,插入排序仍然是线性算法。
因而,插入排序不适合对于数据量比较大的排序应用。但是,如果需要排序的数据量很小,例如,量级小于千,那么插入排序还是一个不错的选择。
冒泡排序
步骤:(从后往前)
- 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
稳定
空间复杂度O(1)
时间复杂度O(n2)
空间复杂度O(1)
时间复杂度O(n2)
冒泡排序的最坏时间复杂度为O(n2)。 算法的平均时间复杂度为O(n2) 。冒泡排序最好的时间复杂度为O(n)。
快速排序
原理,通过一趟扫描将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,
然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列
不稳定,时间复杂度 最理想 O(nlogn) 最差时间O(n^2) 平均复杂度O(nlogn)
堆排序
这里的堆(二叉堆),指得不是堆栈的那个堆,而是一种数据结构。
堆可以视为一棵完全的二叉树,完全二叉树的一个“优秀”的性质是,除了最底层之外,每一层都是满的,这使得堆可以利用数组来表示,每一个结点对应数组中的一个元素.
数组与堆之间的关系
什么是最大堆
堆中每个父节点的元素值都大于等于其孩子结点(如果存在),这样的堆就是一个最大堆
因此,最大堆中的最大元素值出现在根结点(堆顶)
堆排序就是把堆顶的最大数取出,
将剩余的堆继续调整为最大堆,具体过程在第二块有介绍,以递归实现
不稳定,时间复杂度 最理想 O(nlogn) 最差时间O(nlogn) 平均复杂度O(nlogn)
时间复杂度和空间复杂度
时间复杂度是程序运行的时间,也可以说是次数;
空间复杂度是程序占用的空间;
精辟:
要在 hash 表中找到一个元素就是 O(1)
要在无序数组中找到一个元素就是 O(n)
访问数组的第 n 个元素是 O(1)
访问链表的第 n 个元素是 O(n)
要在无序数组中找到一个元素就是 O(n)
访问数组的第 n 个元素是 O(1)
访问链表的第 n 个元素是 O(n)