JavaScript实现的九种排序算法


Posted in Javascript onMarch 04, 2019

前言

排序是数据结构主要内容,并不限于语言主要在于思想;大学曾经用C语言研究过一段时间的排序实现, 这段时间有空用JS再将排序知识点熟悉一遍。

下面话不多说了,来一起看看详细的介绍吧

一、代码汇总(一)

1、冒泡排序

2、改进版冒泡排序

3、选择排序

4、直接插入排序

5、二分插入排序

/*
 * @Author: laifeipeng 
 * @Date: 2019-02-20 10:00:36 
 * @Last Modified by: laifeipeng
 * @Last Modified time: 2019-02-21 11:57:58
 */

/********* 1、冒泡排序 **********/
// 很常见很容易理解的排序算法, 排序思路:遍历数组,每次遍历就将最大(或最小)值推至最前。越往后遍历查询次数越少
const bubbleSort = arr => {
 const list = arr.slice(); //保证函数为纯函数
 const len = list.length;
 for (let i = 0; i < len; i++) {
 for (let j = len - 1; j > i; j--) {
  if (list[j] < list[j - 1]) {
  [list[j - 1], list[j]] = [list[j], list[j - 1]];
  }
 }
 }
 return list;
}

/********* 2、改进版冒泡排序 **********/
// 对上述冒泡排序的一种优化, 优化思路:当一次遍历前后数组不产生变化时,说明该数组已经有序,结束排序。
const bubbleSort2 = arr => {
 const list = arr.slice(); //保证函数为纯函数
 const len = list.length;
 for (let i = 0; i < len; i++) {
 let exchange = false;
 for (let j = len - 1; j > i; j--) {
  if (list[j] < list[j - 1]) {
  [list[j - 1], list[j]] = [list[j], list[j - 1]];
  exchange = true;
  }
 }
 if (!exchange) return list
 }
 return list;
}

/********* 3、选择排序 **********/
// 在无序区中选出最小的元素,然后将它和无序区的第一个元素交换位置。
const selectionSort = arr => {
 const list = arr.slice(); //保证函数为纯函数
 const len = list.length;
 for (let i = 0; i < len; i++) {
 let k = i
 for (let j = len - 1; j > i; j--) {
  if (list[j] < list[k]) k = j;
 }
 if (k !== i) {
  [list[k], list[i]] = [list[i], list[k]];
 }
 }
 return list;
}

/********* 4、直接插入排序 **********/
// 每次选择无序区第一个元素插入到有序区,并排序
const insertSort = arr => {
 const list = arr.slice(); //保证函数为纯函数
 const len = list.length;
 for (let i = 1; i < len; i++) {
 const tmp = list[i];
 let j = i - 1;
 while (j >= 0 && tmp < list[j]) {
  list[j + 1] = list[j];
  j--;
 }
 list[j + 1] = tmp;
 }
 return list;
}

/********* 5、二分插入排序 **********/
// 插入排序的一种优化实现, 通过二分法减少遍历时间(以前是从某边开始依次比较,现在从中间开始比较,减少比较次数)
// 注意,数组很大才能提现二分插入的优势
const insertSort2 = arr => {
 const list = arr.slice(); //保证函数为纯函数
 const len = list.length;
 for (let i = 1; i < len; i++) {
 const tmp = list[i];
 let low = 0;
 let high = i - 1;
 let j = i - 1;
 while (low <= high) {
  const mid = ~~((low + high) / 2);
  if (tmp < list[mid]) {
  high = mid - 1;
  } else {
  low = mid + 1;
  }
 }
 while (j > high) {
  list[j + 1] = list[j];
  j--;
 }
 list[j + 1] = tmp;
 }
 return list;
}

2、代码汇总(二)

6、快速排序

7、原地算法快速排序

8、希尔排序

堆排序、归并排序(js实现无优势,不作实现)

/********* 6、快速排序 **********/
const quickSort1 = arr => {
 const list = arr.slice(); //为了保证这个函数是纯函数,拷贝一次数组
 if (list.length <= 1) return list;
 const pivot = list.splice(0, 1)[0]; //选第一个作为基数,并把基数从数组里面删除
 const left = [];
 const right = [];
 for (let i = 0, len = list.length; i < len; i++) { //从0开始
 if (list[i] < pivot) {
  left.push(list[i]);
 } else {
  right.push(list[i]);
 }
 }
 return [...quickSort(left), pivot, ...quickSort(right)];
}

// 上面const pivot = list.splice(0, 1)[0]; 如果想直接改为list[0],那么后面循环的时候要从i=1开始
const quickSort2 = arr => {
 const list = arr.slice(); //为了保证这个函数是纯函数,拷贝一次数组
 if (list.length <= 1) return list;
 const pivot = list[0]; //选第一个作为基数
 const left = [];
 const right = [];
 for (let i = 1, len = list.length; i < len; i++) { //从1开始
 if (list[i] < pivot) {
  left.push(list[i]);
 } else {
  right.push(list[i]);
 }
 }
 return [...quickSort(left), pivot, ...quickSort(right)];
}

/********* 7、原地算法快速排序 **********/
const quickSort = arr => {
 const list = arr.slice() // 为了保证这个函数是纯函数拷贝一次数组
 const sort = (arr, left = 0, right = arr.length - 1) => {
 if (left >= right) {//如果左边的索引大于等于右边的索引说明整理完毕
  return;
 }
 let i = left;
 let j = right;
 const baseVal = arr[j]; // 取无序数组最后一个数为基准值
 while (i < j) {   //把所有比基准值小的数放在左边大的数放在右边
  while (i < j && arr[i] <= baseVal) { //找到一个比基准值大的数交换
  i++;
  }
  arr[j] = arr[i]; // 将较大的值放在右边如果没有比基准值大的数就是将自己赋值给自己(i 等于 j)
  while (j > i && arr[j] >= baseVal) { //找到一个比基准值小的数交换
  j--;
  }
  arr[i] = arr[j]; // 将较小的值放在左边如果没有找到比基准值小的数就是将自己赋值给自己(i 等于 j)
 }
 arr[j] = baseVal; // 将基准值放至中央位置完成一次循环(这时候 j 等于 i )
 sort(arr, left, j - 1); // 将左边的无序数组重复上面的操作
 sort(arr, j + 1, right); // 将右边的无序数组重复上面的操作
 }
 sort(list);
 return list;
}

/********* 8、希尔排序 **********/
// 排序思路:先将整个待排序记录序列分割成若干个子序列,在序列内分别进行直接插入排序,待整个序列基本有序时,再对全体记录进行一次直接插入排序。
const shellSort = arr => {
 const list = arr.slice(); //保证函数为纯函数
 const len = list.length;
 let gap = ~~(len / 2);
 while (gap > 0) {
 for (let i = gap; i < len; i++) {
  const tmp = list[i];
  let j = i - gap;
  while (j >= 0 && tmp < list[j]) {
  list[j + gap] = list[j];
  j = j - gap;
  }
  list[j + gap] = tmp;
 }
 gap = ~~(gap / 2);
 }
 return list;
}

JavaScript实现的九种排序算法

3、效果图

JavaScript实现的九种排序算法

JavaScript实现的九种排序算法

4、解答

1、如何在控制台打印出上面图片中的彩色效果,eg:

const logStep = (i, leftArr, rightArr) => 
console.log(`%c 第${i}趟排序:%c ${arrStr(leftArr)} %c${arrStr(rightArr)} `, 'color:green', 'color:red', 'color:blue');

2、交换数组2元素:

// 交换下标为i,k的数组元素
[list[k], list[i]] = [list[i], list[k]];

3、所有源码github地址:

https://github.com/laifeipeng/utils/blob/master/sort/sort.js

4、彩色打印效果的github地址:

https://github.com/laifeipeng/utils/blob/master/sort/test.js

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
传智播客学习之JavaScript基础篇
Nov 13 Javascript
JS的replace方法详细介绍
Nov 09 Javascript
Javascript学习笔记之 函数篇(三) : 闭包和引用
Nov 23 Javascript
JS+CSS模拟可以无刷新显示内容的留言板实例
Mar 03 Javascript
jQuery标签编辑插件Tagit使用指南
Apr 21 Javascript
jquery简单的弹出层浮动层代码
Apr 27 Javascript
JavaScript调用客户端Java程序的方法
Jul 27 Javascript
jQuery解决input元素的blur事件和其他非表单元素的click事件冲突问题
Aug 15 Javascript
Javascript Function.prototype.bind详细分析
Dec 29 Javascript
AngularJS实现select的ng-options功能示例
Jul 12 Javascript
vue实现的微信机器人聊天功能案例【附源码下载】
Feb 18 Javascript
js实现select下拉框选择
Jan 11 Javascript
如何在JavaScript中优雅的提取循环内数据详解
Mar 04 #Javascript
iview tabs 顶部导航栏和模块切换栏的示例代码
Mar 04 #Javascript
Vuex mutitons和actions初使用详解
Mar 04 #Javascript
JS重学系列之聊聊new操作符
Mar 04 #Javascript
jQuery实现的导航条点击后高亮显示功能示例
Mar 04 #jQuery
ES10 特性的完整指南小结
Mar 04 #Javascript
node.js使用express框架进行文件上传详解
Mar 03 #Javascript
You might like
发款php蜘蛛统计插件只要有mysql就可用
2010/10/12 PHP
Yii2.0表关联查询实例分析
2016/07/18 PHP
实例讲解PHP表单验证功能
2019/02/15 PHP
javascript 面向对象编程 万物皆对象
2009/09/17 Javascript
一个简单的jQuery插件ajaxfileupload.js实现ajax上传文件例子
2014/06/26 Javascript
JsRender实用入门教程
2014/10/31 Javascript
node.js中的fs.fstat方法使用说明
2014/12/15 Javascript
JavaScript中的setMilliseconds()方法使用详解
2015/06/11 Javascript
Javascript基础之数组的使用
2016/05/13 Javascript
AngularJS基础 ng-csp 指令详解
2016/08/01 Javascript
轻松掌握JavaScript中介者模式
2016/08/26 Javascript
图片上传之FileAPI与NodeJs
2017/01/24 NodeJs
AngularJS学习第一篇 AngularJS基础知识
2017/02/13 Javascript
AngularJS通过ng-Img-Crop实现头像截取的示例
2017/08/17 Javascript
vue生成token并保存到本地存储中
2018/07/17 Javascript
Vuex 在Vue 组件中获得Vuex 状态state的方法
2018/08/27 Javascript
vue 项目中使用Loading组件的示例代码
2018/08/31 Javascript
如何在wxml中直接写js代码(wxs)
2019/11/14 Javascript
[06:16]DOTA2守卫传承者——职业选手谈心路历程
2015/02/26 DOTA
Python利用递归和walk()遍历目录文件的方法示例
2017/07/14 Python
浅谈python中的正则表达式(re模块)
2017/10/17 Python
python中os和sys模块的区别与常用方法总结
2017/11/14 Python
对python中词典的values值的修改或新增KEY详解
2019/01/20 Python
浅析python,PyCharm,Anaconda三者之间的关系
2019/11/27 Python
opencv 图像加法与图像融合的实现代码
2020/07/08 Python
Python使用urlretrieve实现直接远程下载图片的示例代码
2020/08/17 Python
Canon佳能美国官方商店:购买数码相机、数码单反相机、镜头和打印机
2016/11/15 全球购物
Under Armour安德玛中国官网:美国高端运动科技品牌
2018/03/09 全球购物
全球异乡人的跨境社交电商平台:Kouhigh口嗨网
2020/07/24 全球购物
网络工程系信息安全技术专业大学生求职信
2013/10/22 职场文书
班长自荐书范文
2014/02/11 职场文书
理工大学毕业生自荐信范文
2014/02/22 职场文书
学校党的群众路线教育实践活动对照检查材料
2014/09/24 职场文书
晋江市委常委班子四风问题整改工作方案
2014/10/26 职场文书
2015年春节标语口号
2014/12/09 职场文书
浅谈tf.train.Saver()与tf.train.import_meta_graph的要点
2021/05/26 Python