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 相关文章推荐
jquery tools之tabs 选项卡/页签
Jul 25 Javascript
基于jquery点击自以外任意处,关闭自身的代码
Feb 10 Javascript
这些年、我收集的JQuery代码小结
Aug 01 Javascript
IE网页js语法错误2行字符1、FF中正常的解决方法
Sep 09 Javascript
JavaScript中split与join函数的进阶使用技巧
May 03 Javascript
详解ES6中的let命令
Apr 05 Javascript
React组件的三种写法总结
Jan 12 Javascript
SVG动画vivus.js库使用小结(实例代码)
Sep 14 Javascript
three.js 入门案例详解
Jan 23 Javascript
vue里面使用mui的弹出日期选择插件实例
Sep 16 Javascript
详解wepy开发小程序踩过的坑(小结)
May 22 Javascript
vue路由缓存的几种实现方式小结
Feb 02 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
星际初学者游戏中永远要做的事
2020/03/04 星际争霸
php数组函数序列之array_search()- 按元素值返回键名
2011/11/04 PHP
php计划任务之ignore_user_abort函数实现方法
2015/01/08 PHP
使用php的HTTP请求的库Requests实现美女图片墙
2015/02/22 PHP
ModelDialog JavaScript模态对话框类代码
2011/04/17 Javascript
Javascript insertAfter() 实现函数代码
2011/10/12 Javascript
JS判断数组中是否有重复值得三种实用方法
2013/08/16 Javascript
推荐9款炫酷的基于jquery的页面特效
2014/12/07 Javascript
使用javascript实现json数据以csv格式下载
2015/01/09 Javascript
JS基于面向对象实现的放烟花效果
2015/05/07 Javascript
Jquery1.9.1源码分析系列(十五)动画处理之外篇
2015/12/04 Javascript
Servlet实现文件上传,可多文件上传示例
2016/12/05 Javascript
jQuery实现的弹幕效果完整实例
2017/09/06 jQuery
说说AngularJS中的$parse和$eval的用法
2017/09/14 Javascript
Webpack框架核心概念(知识点整理)
2017/12/22 Javascript
Vue 利用指令实现禁止反复发送请求的两种方法
2019/09/15 Javascript
vue-socket.io跨域问题有效解决方法
2020/02/11 Javascript
JavaScript 禁止用户保存图片的实现代码
2020/04/28 Javascript
JavaScript 闭包的使用场景
2020/09/17 Javascript
React倒计时功能实现代码——解耦通用
2020/09/18 Javascript
vue-openlayers实现地图坐标弹框效果
2020/09/24 Javascript
[02:31]DOTA2帕克 英雄基础教程
2013/11/26 DOTA
深入解析Python中的集合类型操作符
2015/08/19 Python
详谈python中冒号与逗号的区别
2018/04/18 Python
Python WSGI的深入理解
2018/08/01 Python
Python requests库用法实例详解
2018/08/14 Python
Django之choices选项和富文本编辑器的使用详解
2020/04/01 Python
解决Opencv+Python cv2.imshow闪退问题
2020/04/24 Python
使用keras2.0 将Merge层改为函数式
2020/05/23 Python
CSS3+js实现简单的时钟特效
2015/03/18 HTML / CSS
Clarks英国官方网站:全球领军鞋履品牌
2016/11/26 全球购物
Zavvi西班牙:电子游戏、极客服装、Blu-ray、Funko Pop等
2019/05/03 全球购物
数据库方面面试题
2012/04/22 面试题
刘胡兰的英雄事迹材料
2014/02/11 职场文书
机械机修工岗位职责
2014/08/03 职场文书
员工规章制度范本
2015/08/07 职场文书