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 相关文章推荐
IE与Firefox下javascript getyear年份的兼容性写法
Dec 20 Javascript
JavaScript 计算当天是本年本月的第几周
Mar 22 Javascript
Mootools 1.2 手风琴(Accordion)教程
Sep 15 Javascript
js实现上传图片预览的方法
Feb 09 Javascript
JS获取字符串实际长度(包含汉字)的简单方法
Aug 11 Javascript
EasyUI Combobox设置默认值 获取text的方法
Nov 28 Javascript
Javascript实现时间倒计时效果
Jul 15 Javascript
JS正则表达式常见用法实例详解
Jun 19 Javascript
vue脚手架搭建项目的兼容性配置详解
Jul 17 Javascript
原生js实现移动端Touch轮播图的方法步骤
Jan 03 Javascript
Vue实现导航栏的显示开关控制
Nov 01 Javascript
JavaScript的console命令使用实例
Dec 03 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学习笔记之数组篇
2011/06/28 PHP
纯php生成随机密码
2015/10/30 PHP
win平台安装配置Nginx+php+mysql 环境
2016/01/12 PHP
php json_encode与json_decode详解及实例
2016/12/13 PHP
Mac系统下安装PHP Xdebug
2018/03/30 PHP
Auntion-TableSort国人写的一个javascript表格排序的东西
2007/11/12 Javascript
深入理解JavaScript系列(15) 函数(Functions)
2012/04/12 Javascript
jquery方法+js一般方法+js面向对象方法实现拖拽效果
2012/08/30 Javascript
jQuery图片轮播的具体实现
2013/09/11 Javascript
基于jquery的手风琴图片展示效果实现方法
2014/12/16 Javascript
js中取得变量绝对值的方法
2015/01/03 Javascript
基于jquery实现页面滚动时顶部导航显示隐藏
2020/04/20 Javascript
原生javascript实现图片无缝滚动效果
2016/02/12 Javascript
基于iScroll实现下拉刷新和上滑加载效果
2017/07/18 Javascript
微信小程序 数据绑定及运算的简单实例
2017/09/20 Javascript
Servlet3.0与纯javascript通过Ajax交互的实例详解
2018/03/18 Javascript
基于Vue实现图片在指定区域内移动的思路详解
2018/11/11 Javascript
详解React中合并单元格的正确写法
2019/01/08 Javascript
8个有意思的JavaScript面试题
2019/07/30 Javascript
[04:17]DOTA2完美盛典,rOtk、BurNIng携手巴图演唱《倔强》
2017/11/28 DOTA
python连接MySQL数据库实例分析
2015/05/12 Python
简单介绍Python中的decode()方法的使用
2015/05/18 Python
python程序封装为win32服务的方法
2021/03/07 Python
DataFrame:通过SparkSql将scala类转为DataFrame的方法
2019/01/29 Python
Python 中判断列表是否为空的方法
2019/11/24 Python
Django基于客户端下载文件实现方法
2020/04/21 Python
java字符串格式化输出实例讲解
2021/01/06 Python
马克华菲官方商城:Mark Fairwhale
2016/09/04 全球购物
为奢侈时尚带来了慈善元素:Olivela
2018/09/29 全球购物
小学生九一八纪念日83周年演讲稿500字
2014/09/17 职场文书
监察局领导班子四风问题整改措施思想汇报
2014/10/05 职场文书
领导个人查摆剖析材料
2014/10/29 职场文书
五年级语文教学反思
2016/03/03 职场文书
python元组打包和解包过程详解
2021/08/02 Python
Python Django模型详解
2021/10/05 Python
CSS实现渐变色边框(Gradient borders)的5种方法
2022/03/25 HTML / CSS