本篇文章讲的是以下五种常用的排序算法:

一、冒泡排序

1、原理

每次从前往后遍历整个数组,每一项与其后一项进行对比,若符合要求(从大到小或从小到大),就交换位置。

一遍循环结束后,最大(小)的值就会被排在数组结尾,即每次循环能排好一位,所以要遍历n遍,才能把整个数组排好。

2、特点

实现简单,效率低,排序是稳定的。

3、算法复杂度

时间复杂度O(n^2),空间复杂度O(1)

4、代码实现

function bubbleSort (array) {for (let i = 0; i < array.length; i++) {for (let j = 0; j < array.length - 1; j++) {if (array[j] > array[j+1]) {[array[j+1], array[j]] = [array[j], array[j+1]];}}}return array;
}
const arr = [3,121,453,32,7,90,18,9];
console.log(bubbleSort(arr));
// [
//     3,  7,   9,  18,
//     32, 90, 121, 453
//   ]

但是其实,没次遍历后,都能排好一位,n次即n位被排好序,那么排好序的位置就不需要在参与之后的遍历了,所以优化后的代码:

function bubbleSort (array) {for (let i = 0; i < array.length; i++) {for (let j = 0; j < array.length - 1 - i; j++) {if (array[j] > array[j+1]) {[array[j+1], array[j]] = [array[j], array[j+1]];}}}return array;
}
const arr = [3,121,453,32,7,90,18,9];
console.log(bubbleSort(arr));
// [
//     3,  7,   9,  18,
//     32, 90, 121, 453
//   ]

二、插入排序

1、原理

从第二项开始,依次将每一项,插入到该项前边的数组(已排好序)

2、特点

实现较简单,排序稳定

3、算法复杂度

时间复杂度O(n^2),空间复杂度O(1)

4、代码实现

function insertionSort (array) {for (let i = 1; i < array.length; i++) {let temp = array[i];for (let j = i - 1; j >= 0; j--) {if (temp < array[j]) {[array[j+1], array[j]] = [array[j], temp];  }}}return array;
}
const arr = [3,121,453,32,7,90,18,9];
console.log(insertionSort(arr));
// [
//     3,  7,   9,  18,
//     32, 90, 121, 453
//   ]

但是其实,在内层遍历插入时,其实可以选择用二分查找法,因为前边的项都是已经排好序的,优化后的时间复杂度为O(nlogn),优化后的代码如下:

function insertionSort (array) {for (let i = 1; i < array.length; i++) {let temp = array[i];let low = 0, high = i - 1, mid;while (low <= high) {mid = Math.floor((low + high) / 2);if (temp < array[mid]) {high = mid - 1;} else {low = mid + 1;}}// low为插入位置,插入位置low后的依次向后移for (let j = i; j > low; j--){array[j] = array[j - 1];}array[low] = temp;}return array;
}
const arr = [3,121,453,32,7,90,18,9];
console.log(insertionSort(arr));
// [
//     3,  7,   9,  18,
//     32, 90, 121, 453
//   ]

三、选择排序

1、原理

每次找出最小(大)值、第二小(大)的值,依次与数组的第一位、第二位……交换位置

2、特点

排序不稳定

3、算法复杂度

时间复杂度O(n^2),空间复杂度O(1)

4、代码实现

function selectionSort (array) {for (let i = 0; i < array.length; i++) {let min = array[i];for (let j = i; j < array.length; j++) {const element = array[j];if (min > element) {min = element;}}let minIndex = array.indexOf(min);[array[i], array[minIndex]] = [array[minIndex], array[i]];}return array;
}
const arr = [3,121,453,32,7,90,18,9];
console.log(selectionSort(arr));
// [
//     3,  7,   9,  18,
//     32, 90, 121, 453
//   ]

四、快速排序

1、原理

随机从数组中找一个基准值,然后将比基准值小的放一边,比基准值大的放另一边,递归不断对左右两部分数组进行排序,最后排好的就是最终结果。

2、特点

快,对数据非常大的效率高,不稳定,需要额外的两个数组

3、算法复杂度

时间复杂度平均O(nlogn),最坏O(n^2),空间复杂度O(logn)

4、代码实现

const quickSort = function (arr) {if(arr.length < 2) return arr;// 随机选择0~arr.length之间选一个基准值const pivot = Math.floor(Math.random() * arr.length);// 声明两个数组,分别用于存放比基准值小的数据和比基准值大的数据let minArr = [];let maxArr = [];for(let i = 0; i < arr.length; i++){// 大于基准值就放maxArr里if(arr[i] >= arr[pivot] && i !== pivot){maxArr.push(arr[i]);}// 小于基准值就放minArr里if(arr[i] < arr[pivot] && i !== pivot){minArr.push(arr[i])}}// 分别对基准值划分出来的数组递归调用快速排序,然后合并数组return [...quickSort(minArr), arr[pivot], ...quickSort(maxArr)];
}
const arr = [3,121,453,32,7,90,18,9];
console.log(quickSort(arr));

五、归并排序

1、原理

百度百科是这样说的:采用分治法,将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。但是其实这是核心思想,前边还需要做的就是"",将数组不断地平分,直到不能在分为止。

算法主要分成四个步骤

  • 数组分成两半,left和right
  • 递归处理left
  • 递归处理right
  • 合并二者结果

"治"的过程,就是合并,是从两个数组的第一位开始依次比较,较小的一个push到新数组中,直到结束,新数组就是排好序的结果。

2、特点

排序稳定,需要额外空间,排序比较优秀了

3、算法复杂度

时间复杂度为O(nlogn),空间复杂度为O(n)

4、代码实现

const mergeSort = arr => {//递归方法const len = arr.length;if (len < 2) {return arr;}let middle = Math.floor(len / 2),left = mergeSort(arr.slice(0, middle)),right = mergeSort(arr.slice(middle)); // 拆分为两个子数组return merge(left, right);
};
const merge = (left, right) => {let result = [];while (left.length && right.length) {// 注意: 判断的条件是小于或等于,如果只是小于,那么排序将不稳定.if (left[0] <= right[0]) {result.push(left.shift());} else {result.push(right.shift());}}if (left.length) {result = result.concat(left);}if (right.length) {result = result.concat(right);}return result;
};
const arr = [3,121,453,32,7,90,18,9];
console.log(mergeSort(arr));
// [
//     3,  7,   9,  18,
//     32, 90, 121, 453
//   ]

比较:

算法名称 平均时间情况 最好情况 最坏情况 空间复杂度 稳定性
冒泡排序 O(n^2) O(n) O(n^2) O(1) 稳定
插入排序 O(n^2) O(n) O(n^2) O(1) 稳定
选择排序 O(n^2) O(n^2) O(n^2) O(1) 不稳定
快速排序 O(nlogn) O(nlogn) O(n^2) O(logn) 不稳定
归并排序 O(nlogn) O(nlogn) O(nlogn) O(n) 稳定

五种常用排序算法总结相关推荐

  1. [转载] java实现四种常用排序算法

    参考链接: 用Java排序 四种常用排序算法 ##注:从小到大排 ##冒泡排序## 特点:效率低,实现简单 思想:每一趟将待排序序列中最大元素移到最后,剩下的为新的待排序序列,重复上述步骤直到排完所有 ...

  2. 五种内部排序算法性能比较——C++

    **五种内部排序算法性能比较 ** 1.直接插入排序算法 将一个待排序的记录插入到若干个已排好序的有序记录中的适当位置,从而得到一个新的.记录数增加1的有序数据序列,直到插入完成.在最开始,整个有序数 ...

  3. 视觉直观感受7种常用排序算法

    视觉直观感受若干常用排序算法 1 快速排序 介绍: 快速排序是由东尼·霍尔所发展的一种排序算法.在平均状况下,排序 n 个项目要Ο(n log n)次比较.在最坏状况下则需要Ο(n2)次比较,但这种状 ...

  4. 8种常用排序算法稳定性分析

    选择排序.快速排序.希尔排序.堆排序不是稳定的排序算法 冒泡排序.插入排序.归并排序和基数排序都是稳定的排序算法. [1]为什么要区分排序算法的稳定性? 排序算法的稳定性通俗地讲就是能保证排序前两个相 ...

  5. 10种常用排序算法实现

    在使用VBA进行写程序时,经常会做排序,下面将会给出一些常用的排序算法的实现,方便大家写程序参考,若代码中出现了错误,欢迎高手指正. 主要算法有: 1.(冒泡排序)Bubble sort 2.(选择排 ...

  6. 八种常用排序算法参考

    写在前面: 因为网络上有很多篇讲排序算法的,所以这里就不详细讲了,只作为参考和自己查阅 当然了,虽然篇幅也会短很多,但部分重点和要点还在 八种排序算法分别是: ①选择排序: ②冒泡排序: ③插入排序: ...

  7. 9种常用排序算法总结(超详细)

    以int型数据为例,且0号下标数组用来做为交换辅助空间,数据从1号下标开始存储 一.插入排序 基本思想:每一趟将一个待排序的记录,按其关键字的大小插入到已经排好序的一组记录的适当位置上,直到全部待排序 ...

  8. 【轻松学排序算法】眼睛直观感受几种常用排序算法(转)

    1 快速排序 介绍: 快速排序是由东尼·霍尔所发展的一种排序算法.在平均状况下,排序 n 个项目要Ο(n log n)次比较.在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见.事实上,快速排序通 ...

  9. java list的排序算法_JAVA排序汇总(List、数组排序、几种常用排序算法)

    List排序 1.使用Collections的sort(List list)方法对List集合进行从小到大排序 /*** 使用Collections的sort(List list)方法对List集合进 ...

最新文章

  1. 第 14 章 Networking
  2. C#中实现窗体程序的退出按钮功能
  3. [Python图像处理] 二十五.图像特效处理之素描、怀旧、光照、流年以及滤镜特效
  4. Flink的基于ValueState的状态机
  5. 【QGIS入门实战精品教程】4.1:QGIS栅格数据地理配准完整操作流程
  6. 大叔手记(21):汤姆大叔博客园开博100天总结
  7. mysql查其它用户的表_mysql sql查询如何实现发私信用户和其他用户的列表?要求消重所有重复的用户结果...
  8. ffdshow 源代码分析1 : 整体结构
  9. jackson 用法总结
  10. 在nameSilo购买域名
  11. 循序渐进学Docker pdf
  12. 开启 Kerberos 安全的大数据环境中,Yarn Container 启动失败导致作业失败
  13. 从阿里巴巴icon引入图标到微信小程序(可以改变大小,颜色)
  14. root过的安卓机器,安卓机怎样root
  15. 职教云python题和答案_智慧职教云课堂APPPython程序设计题库及答案
  16. scratch项目学习计划
  17. 关键词文章自动生成的四大要点
  18. EasyExcel 实践与源码梳理
  19. 深入理解 Proxy 和 Reflect-- JavaScript
  20. JSP SSH图书系统myeclipse开发sql数据库BS模式java编程mvc结构 详细设计

热门文章

  1. Java8新特性Stream流详解
  2. phpmyadmin新建数据库无权限
  3. 【Java AWT 图形界面编程】LayoutManager 布局管理器 ④ ( GridLayout 网格布局 | GridBagLayout 网格包布局 )
  4. Java //PP1.6 编写一个程序,显示一首歌的一段歌词,并标注合声部分(歌曲自选)。
  5. 初学者JAVA99乘法表
  6. 电压转电流,4-20mA输出电路
  7. js 比较时间的大小
  8. bzoj2018 [Usaco2009 Nov]农场技艺大赛
  9. 【机器学习实战】朴素贝叶斯应用之垃圾邮件过滤
  10. (二)VMware搭建华为FusionCompute6.5.1,可正常使用 —— 开启X11转发,配置桥接,安装FusionCompute