排序算法 是一种能将一串数据依照特定排序方式进行排列的一种算法
这里记录了七种常见的排序算法, 其中稳定的排序算法有冒泡排序, 插入排序, 归并排序, 不稳定的排序算法有选择排序, 希尔排序, 堆排序, 快速排序
冒泡排序
冒泡排序是最简单的排序算法, 它需要从数组第一位开始遍历, 每相邻的两位比较大小, 然后按照递增(或递减)的需求, 交换数字, 直至最大(或最小)移到最后一位, 然后排除排序好的一位, 也就是长度减一, 继续重复地前面的步骤直至排序完成
实现代码:
1 | var swap = function(i, j, arr) { |
时间复杂度: O(n^2)
空间复杂度: O(n)
鸡尾酒排序
鸡尾酒排序是冒泡排序的变形算法, 它与冒泡排序不同的是, 每排序好一位, 将反向继续进行排序
实现代码:
1 | var CocktailSort = function(arr) { |
插入排序
插入排序指的是对未排序的数列, 依次从后向前在已排序的数列中找到相应的位置插入数据
其运作过程:
- 数组第一位看作是已排序好, 从下一位位开始进行向前扫描
- 取出待插入数据, 从后向前比较数值大小, 若待插入数据小于对比数据, 对比数据向后移动一位,重复这一步骤直至待插入数据找到插入位置
- 将待插入数据插入数组,循环继续进行直至数组排序完成
实现代码:
1 | var insertionSort = function(arr) { |
时间复杂度: O(n^2)
空间复杂度: O(n)
归并排序
归并排序是将一组数列分组到最小单位, 再通过每相邻两组中的数值比较合并成一个有序的数列组, 不断地重复这个过程直至所有元素排序完成
实现代码:
1 | var merge = function(left, right) { |
时间复杂度: O(nlogn)
空间复杂度: O(n)
选择排序
选择排序也是一种比较简单的排序算法, 它的运作原理是:
- 先从未排序数列中找到最小(或最大)的数值, 将其放在未排序数列起始位置
- 继续从剩下的未排序的数列中重复上面的过程
实现代码:
1 | var selectionSort = function(arr) { |
时间复杂度: O(n^2)
空间复杂度: O(n^2)
快速排序
快速排序是Javscript中sort方法实现的一种排序算法, 它使用分治法策略, 将数列分成两个子序列进行排序的过程, 具体运作原理为:
- 从数列中取出一个基准数值
- 将小于基准的数据放在左边, 大于基准的数据放在右边
- 递归上面的步骤
实现代码:
1 | var quickSort = function(arr) { |
希尔排序
希尔排序是基于插入排序改进的一种算法, 插入排序对于几乎已排序的数列来说效率最高, 因此希尔排序在这个基础上, 通过将比较的全部数值分区域进行插入排序, 让一个数值可以一次性地移动更大的位置, 再不断地缩小步长直至1, 这时候大部分数据已排好序, 对于插入排序来说效率比较高
实现代码:
1 | var shellSort = function(arr) { |
时间复杂度: O(n)
空间复杂度: O(n)
堆排序
堆排序是利用堆的数据结构设计的一种排序算法, 堆有这近似完全二叉树的结构, 在一维数组中表示:
- 父节点i的左子节点在位置2*i+1
- 父节点i的右子节点在位置2*i+2
- 子节点i的父节点在位置floor((i-1)/2)
在堆排序的操作中, 有:
- 最大堆调整: 将堆的末端子节点作调整, 使子节点永远小于父节点
- 创建最大堆: 将堆所有数据重新排序
- 堆排序: 移除根结点, 并做最大堆调整递归运算
实现代码:
1 | var maxHeapify = function(father, len, array) { |
时间复杂度: O(nlogn)
空间复杂度: O(n)