JavaScript数据结构与算法之基本排序算法定义与效率比较【冒泡、选择、插入排序】


Posted in Javascript onFebruary 21, 2019

本文实例讲述了JavaScript数据结构与算法之基本排序算法定义与效率比较。分享给大家供大家参考,具体如下:

javascript数据结构与算法--基本排序算法(冒泡、选择、排序)及效率比较

一、数组测试平台

javascript数据结构与算法--基本排序(封装基本数组的操作),封装常规数组操作的函数,比如:插入新数据,显示数组数据,还有交换数组元素等操作来调用不同的排序算法

function CArray(numElements) {
  this.dataStore = [];
  this.pos = 0;//是一个索引值,默认为0,从第一个开始
  this.numElements = numElements;//是保存所有的数组元素
  this.insert = insert;//向数组中插入一个元素的方法
  this.toString = toString;//显示数组中所有元素
  this.clear = clear;//清空数组数据
  this.setData = setData;//生成了存储在数组中的随机数字
  this.swap = swap;//交换数组中两个元素的位置
  this.bubbleSort = bubbleSort;
  /*将传入的数组,存储在datastore中*/
  for (var i = 0; i < numElements.length; ++i) {
    this.dataStore[i] = numElements[i];
  }
}
function setData() {
  for (var i = 0; i < this.numElements; ++i) {
    this.dataStore[i] = Math.floor(Math.random() *
      (this.numElements+1));
  }
}
function clear() {
  for (var i = 0; i < this.dataStore.length; ++i) {
    this.dataStore[i] = 0;
  }
}
function insert(element) {
  this.dataStore[this.pos++] = element;
}
function toString() {
  var retstr = "";
  for (var i = 0; i < this.dataStore.length; ++i) {
    retstr += this.dataStore[i] + " ";
    if (i > 0 && i % 10 == 0) {
      retstr += "\n";
    }
  }
  return retstr;
}
function swap(arr, index1, index2) {
  var temp = arr[index1];
  arr[index1] = arr[index2];
  arr[index2] = temp;
}
//测试生成一组数组数据(随机数)
var numElements = 100;
var myNums = new CArray(numElements);
myNums.setData();
console.log(myNums.toString());

17 94 81 80 25 24 73 76 24 35 81
63 81 59 4 76 30 47 73 98 18
54 36 53 47 22 60 88 41 66 24
73 94 40 45 72 74 14 61 92 48
36 12 42 11 12 82 24 84 60 1
17 98 63 36 84 13 18 50 89 26
98 1 6 54 52 69 6 52 98 14
79 28 19 69 76 99 97 100 10 7
24 54 81 73 18 21 45 73 66 30
28 56 54 21 88 31 20 86 48

二、冒泡排序算法

我们先来了解一下冒泡排序算法,它是最慢的排序算法之一,但也是一种最容易实现的排序算法。

之所以叫冒泡排序是因为使用这种排序算法排序时,数据值会像气泡一样从数组的一端漂浮到另一端。

假设正在将一组数字按照升序排列,较大的值会浮动到数组的右侧,而较小的值则会浮动到数组的左侧。

之所以会产生这种现象是因为算法会多次在数组中移动,比较相邻的数据,当左侧值大于右侧值时将它们进行互换。

JS代码如下:

function CArray(numElements) {
  this.dataStore = [];
  this.pos = 0;//是一个索引值,默认为0,从第一个开始
  this.numElements = numElements;//是保存所有的数组元素
  this.insert = insert;//向数组中插入一个元素的方法
  this.toString = toString;//显示数组中所有元素
  this.clear = clear;//清空数组数据
  this.setData = setData;//生成了存储在数组中的随机数字
  this.swap = swap;//交换数组中两个元素的位置
  this.bubbleSort = bubbleSort;//冒泡算法
  /*将传入的数组,存储在datastore中*/
  for (var i = 0; i < numElements.length; ++i) {
    this.dataStore[i] = numElements[i];
  }
}
function setData() {
  for (var i = 0; i < this.numElements; ++i) {
    this.dataStore[i] = Math.floor(Math.random() *
      (this.numElements+1));
  }
}
function clear() {
  for (var i = 0; i < this.dataStore.length; ++i) {
    this.dataStore[i] = 0;
  }
}
function insert(element) {
  this.dataStore[this.pos++] = element;
}
function toString() {
  var retstr = "";
  for (var i = 0; i < this.dataStore.length; ++i) {
    retstr += this.dataStore[i] + " ";
    if (i > 0 && i % 10 == 0) {
      retstr += "\n";
    }
  }
  return retstr;
}
function swap(arr, index1, index2) {
  var temp = arr[index1];
  arr[index1] = arr[index2];
  arr[index2] = temp;
}
function bubbleSort() {
  var numElements = this.dataStore.length;
  for (var outer = numElements; outer >= 2; --outer) {
    for (var inner = 0; inner <= outer-1; ++inner) {
      if (this.dataStore[inner] > this.dataStore[inner+1]) {
        swap(this.dataStore, inner, inner+1);
      }
    }
    console.log("outer为" + outer + ": " + this.toString());
  }
}
//测试冒泡排序算法
var numElements = [2,4,1,3];
var myNums = new CArray(numElements);
console.log("原来的数组:"+myNums.toString());
myNums.bubbleSort();
console.log("排序后的数组:"+myNums.toString());

冒泡算法代码分析如下:

原先数组为 [2,4,1,3];

1. outer为4的时候

    1. inner为0,值为2,inner+1为1,值为4,不符合,不交换。
    2. inner为1,值为4,inner+1为2,值为1,交换,数组变为[2,1,4,3]
    3. inner为2,值为4,inner+1为3,值为3,交换 数组变为[2,1,3,4]
    4. inner为3,值为4,inner+1为4,不符合 不交换。

2. outer为3的时候

    1. inner为0,值为2,inner+1为1,值为1,交换 数组变为[1,2,3,4]
    2. inner为1, 值为2,inner+1为2,值为3 不符合 不交换。
    3. inner为2, 值为3,inner+1为3,值为4,不符合 不交换。

再下面继续循环都不符合条件,所以如上就是最后一步了。这就是冒泡排序。

三、选择排序算法

选择排序从数组的开头开始,将第一个元素和其他元素进行比较。

检查完所有元素后,最小的元素会被放到数组的第一个位置,然后算法会从第二个位置继续。

这个过程一直进行,当进行到数组的倒数第二个位置时,所有的数据便完成了排序。
选择排序会用到嵌套循环。

外循环从数组的第一个元素移动到倒数第二个元素;

内循环从第二个数组元素移动到最后一个元素,查找比当前外循环所指向的元素小的元素。

每次内循环迭代后,数组中最小的值都会被赋值到合适的位置。

JS代码如下:

function CArray(numElements) {
  this.dataStore = [];
  this.pos = 0;//是一个索引值,默认为0,从第一个开始
  this.numElements = numElements;//是保存所有的数组元素
  this.insert = insert;//向数组中插入一个元素的方法
  this.toString = toString;//显示数组中所有元素
  this.clear = clear;//清空数组数据
  this.setData = setData;//生成了存储在数组中的随机数字
  this.swap = swap;//交换数组中两个元素的位置
  this.selectionSort = selectionSort;//选择排序算法
  /*将传入的数组,存储在datastore中*/
  for (var i = 0; i < numElements.length; ++i) {
    this.dataStore[i] = numElements[i];
  }
}
function setData() {
  for (var i = 0; i < this.numElements; ++i) {
    this.dataStore[i] = Math.floor(Math.random() *
      (this.numElements+1));
  }
}
function clear() {
  for (var i = 0; i < this.dataStore.length; ++i) {
    this.dataStore[i] = 0;
  }
}
function insert(element) {
  this.dataStore[this.pos++] = element;
}
function toString() {
  var retstr = "";
  for (var i = 0; i < this.dataStore.length; ++i) {
    retstr += this.dataStore[i] + " ";
    if (i > 0 && i % 10 == 0) {
      retstr += "\n";
    }
  }
  return retstr;
}
function swap(arr, index1, index2) {
  var temp = arr[index1];
  arr[index1] = arr[index2];
  arr[index2] = temp;
}
function selectionSort() {
  var min, temp;
  for (var outer = 0; outer <= this.dataStore.length-2; ++outer) {
    min = outer;
    for (var inner = outer + 1;inner <= this.dataStore.length-1; ++inner) {
      if (this.dataStore[inner] < this.dataStore[min]) {
        min = inner;
      }
    }
    swap(this.dataStore, outer, min);
    console.log("第"+outer +"次:"+myNums.toString());
  }
}
//测试排序算法
var numElements = [2,4,1,3];
var myNums = new CArray(numElements);
console.log("原来的数组:"+myNums.toString());
myNums.selectionSort();
console.log("排序后的数组:"+myNums.toString());

原来的数组:2 4 1 3
第0次:1 4 2 3
第1次:1 2 4 3
第2次:1 2 3 4
排序后的数组:1 2 3 4

四、插入排序算法

插入排序有两个循环。

外循环将数组元素挨个移动,而内循环则对外循环中选中的元素及它前面的那个元素进行比较。

如果外循环中选中的元素比内循环中选中的元素小,那么数组元素会向右移动,为外循环中的这个元素腾出位置

function CArray(numElements) {
  this.dataStore = [];
  this.pos = 0;//是一个索引值,默认为0,从第一个开始
  this.numElements = numElements;//是保存所有的数组元素
  this.insert = insert;//向数组中插入一个元素的方法
  this.toString = toString;//显示数组中所有元素
  this.clear = clear;//清空数组数据
  this.setData = setData;//生成了存储在数组中的随机数字
  this.swap = swap;//交换数组中两个元素的位置
  this.insertionSort = insertionSort;//插入排序算法
  /*将传入的数组,存储在datastore中*/
  for (var i = 0; i < numElements.length; ++i) {
    this.dataStore[i] = numElements[i];
  }
}
function setData() {
  for (var i = 0; i < this.numElements; ++i) {
    this.dataStore[i] = Math.floor(Math.random() *
      (this.numElements+1));
  }
}
function clear() {
  for (var i = 0; i < this.dataStore.length; ++i) {
    this.dataStore[i] = 0;
  }
}
function insert(element) {
  this.dataStore[this.pos++] = element;
}
function toString() {
  var retstr = "";
  for (var i = 0; i < this.dataStore.length; ++i) {
    retstr += this.dataStore[i] + " ";
    if (i > 0 && i % 10 == 0) {
      retstr += "\n";
    }
  }
  return retstr;
}
function swap(arr, index1, index2) {
  var temp = arr[index1];
  arr[index1] = arr[index2];
  arr[index2] = temp;
}
function insertionSort() {
  var temp, inner;
  //外循环将数组元素挨个移动
  for (var outer = 1; outer <= this.dataStore.length-1; ++outer) {
    temp = this.dataStore[outer];//外循环选中的元素temp
    inner = outer;
    //内循环对外循环中选中的元素temp与temp前面的元素一个个进行比较。
    //如果外循环中选中的元素temp比内循环中选中的元素小,那么数组元素会向右移动,为外循环中的这个元素腾出位置
    while (inner > 0 && (this.dataStore[inner-1] >= temp)) {
      this.dataStore[inner] = this.dataStore[inner-1];
      --inner;
    }
    this.dataStore[inner] = temp;
    console.log("第"+outer+"次:"+myNums.toString());
  }
}
//测试排序算法
var numElements = [9,1,8,6,2,3,5,4];
var myNums = new CArray(numElements);
console.log("原来的数组:"+myNums.toString());
myNums.insertionSort();
console.log("排序后的数组:"+myNums.toString());

原来的数组:9 1 8 6 2 3 5 4 //先用1和1前面的对比,9比1大,所以9向右移动一个位置,给1腾位置
      第1次:1 9 8 6 2 3 5 4 //用8与8前面的对比,9比8大,所以9向右移动一个位置,给8腾位置
      第2次:1 8 9 6 2 3 5 4 //用6与6前面的对比,8,9比6大,所以8、9向右移动一个位置,给6腾位置
      第3次:1 6 8 9 2 3 5 4
      第4次:1 2 6 8 9 3 5 4
      第5次:1 2 3 6 8 9 5 4
      第6次:1 2 3 5 6 8 9 4
      第7次:1 2 3 4 5 6 8 9
排序后的数组:1 2 3 4 5 6 8 9

五、基本排序算法的效率比较

function CArray(numElements) {
  this.dataStore = [];
  this.pos = 0;//是一个索引值,默认为0,从第一个开始
  this.numElements = numElements;//是保存所有的数组元素
  this.insert = insert;//向数组中插入一个元素的方法
  this.toString = toString;//显示数组中所有元素
  this.clear = clear;//清空数组数据
  this.setData = setData;//生成了存储在数组中的随机数字
  this.swap = swap;//交换数组中两个元素的位置
  this.bubbleSort = bubbleSort;//冒泡排序算法
  this.selectionSort = selectionSort;//选择排序算法
  this.insertionSort = insertionSort;//插入排序算法
  /*将传入的数组,存储在datastore中*/
  for (var i = 0; i < numElements.length; ++i) {
    this.dataStore[i] = numElements[i];
  }
}
function setData() {
  for (var i = 0; i < this.numElements; ++i) {
    this.dataStore[i] = Math.floor(Math.random() *
      (this.numElements+1));
  }
}
function clear() {
  for (var i = 0; i < this.dataStore.length; ++i) {
    this.dataStore[i] = 0;
  }
}
function insert(element) {
  this.dataStore[this.pos++] = element;
}
function toString() {
  var retstr = "";
  for (var i = 0; i < this.dataStore.length; ++i) {
    retstr += this.dataStore[i] + " ";
    if (i > 0 && i % 10 == 0) {
      retstr += "\n";
    }
  }
  return retstr;
}
function swap(arr, index1, index2) {
  var temp = arr[index1];
  arr[index1] = arr[index2];
  arr[index2] = temp;
}
function bubbleSort() {
  var numElements = this.dataStore.length;
  for (var outer = numElements; outer >= 2; --outer) {
    for (var inner = 0; inner <= outer-1; ++inner) {
      if (this.dataStore[inner] > this.dataStore[inner+1]) {
        swap(this.dataStore, inner, inner+1);
      }
    }
//    console.log("outer为" + outer + ": " + this.toString());
  }
}
function selectionSort() {
  var min, temp;
  for (var outer = 0; outer <= this.dataStore.length-2; ++outer) {
    min = outer;
    for (var inner = outer + 1;inner <= this.dataStore.length-1; ++inner) {
      if (this.dataStore[inner] < this.dataStore[min]) {
        min = inner;
      }
    }
    swap(this.dataStore, outer, min);
//    console.log("第"+outer +"次:"+this.toString());
  }
}
function insertionSort() {
  var temp, inner;
  //外循环将数组元素挨个移动
  for (var outer = 1; outer <= this.dataStore.length-1; ++outer) {
    temp = this.dataStore[outer];//外循环选中的元素
    inner = outer;
    //内循环则对外循环中选中的元素与它前面的那个元素进行比较。
    //如果外循环中选中的元素比内循环中选中的元素小,那么数组元素会向右移动,为外循环中的这个元素腾出位置
    while (inner > 0 && (this.dataStore[inner-1] >= temp)) {
      this.dataStore[inner] = this.dataStore[inner-1];
      --inner;
    }
    this.dataStore[inner] = temp;
//    console.log("第"+outer+"次:"+this.toString());
  }
}
/*测试冒泡、选择、插入算法的效率*/
var numElements = 10000;
var nums = new CArray(numElements);
nums.setData();
var start = new Date().getTime();
nums.bubbleSort();
var stop = new Date().getTime();
var elapsed = stop - start;
console.log("用冒泡算法,排序 " + numElements + " 个元素耗时 : " + elapsed + " milliseconds.");
start = new Date().getTime();
nums.selectionSort();
stop = new Date().getTime();
elapsed = stop - start;
console.log("用选择算法,排序 " + numElements + " 个元素耗时: " + elapsed + " milliseconds.");
start = new Date().getTime();
nums.insertionSort();
stop = new Date().getTime();
elapsed = stop - start;
console.log("用插入算法,排序 " + numElements + " 个元素耗时: " + elapsed + " milliseconds.");

运行结果:

JavaScript数据结构与算法之基本排序算法定义与效率比较【冒泡、选择、插入排序】

选择排序和插入排序要比冒泡排序快,插入排序是这三种算法中最快的。

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun测试上述代码运行效果。

Javascript 相关文章推荐
基于jquery实现的类似百度搜索的输入框自动完成功能
Aug 23 Javascript
jQuery蓝色风格滑动导航栏代码分享
Aug 19 Javascript
跟我学习javascript的闭包
Nov 16 Javascript
AngularJs  unit-testing(单元测试)详解
Sep 02 Javascript
JavaScript简单验证表单空值及邮箱格式的方法
Jan 20 Javascript
js基于myFocus实现轮播图效果
Feb 14 Javascript
Vue生命周期示例详解
Apr 12 Javascript
基于JSONP原理解析(推荐)
Dec 04 Javascript
详解Node.js一行命令上传本地文件到服务器
Apr 22 Javascript
vue操作动画的记录animate.css实例代码
Apr 26 Javascript
d3.js 地铁轨道交通项目实战
Nov 27 Javascript
Vue实现图书管理案例
Jan 20 Vue.js
JavaScript数据结构与算法之二叉树插入节点、生成二叉树示例
Feb 21 #Javascript
angularjs实现table表格td单元格单击变输入框/可编辑状态示例
Feb 21 #Javascript
Vue实现table上下移动功能示例
Feb 21 #Javascript
JavaScript数组、json对象、eval()函数用法实例分析
Feb 21 #Javascript
ES6基础之解构赋值(destructuring assignment)
Feb 21 #Javascript
ES6基础之展开语法(Spread syntax)
Feb 21 #Javascript
ES6基础之默认参数值
Feb 21 #Javascript
You might like
php array_unique之后json_encode需要注意
2011/01/02 PHP
php模拟asp中的XmlHttpRequest实现http请求的代码
2011/03/24 PHP
探讨如何把session存入数据库
2013/06/07 PHP
浅谈php和js中json的编码和解码
2016/10/24 PHP
PHP中的异常处理机制深入讲解
2020/11/10 PHP
js 省地市级联选择
2010/02/07 Javascript
JS定时器实例
2013/04/17 Javascript
JQuery的自定义事件代码,触发,绑定简单实例
2013/08/01 Javascript
一个简单的全屏图片上下打开显示网页效果示例
2014/07/08 Javascript
Javascript 拖拽雏形中的一些问题(逐行分析代码,让你轻松了拖拽的原理)
2015/01/23 Javascript
JS实现点击按钮控制Div变宽、增高及调整背景色的方法
2015/08/05 Javascript
微信小程序  简单实例(阅读器)的实例开发
2016/09/29 Javascript
详解Vue源码之数据的代理访问
2018/12/11 Javascript
JavaScript设计模式之装饰者模式实例详解
2019/01/17 Javascript
js数组的基本使用总结
2021/01/18 Javascript
[03:18]DOTA2亚洲邀请赛小组赛第一日 RECAP赛事回顾
2015/01/30 DOTA
Python 正则表达式操作指南
2009/05/04 Python
Python中模拟enum枚举类型的5种方法分享
2014/11/22 Python
Python 冒泡,选择,插入排序使用实例
2015/02/05 Python
解决Python 遍历字典时删除元素报异常的问题
2016/09/11 Python
Python元组及文件核心对象类型详解
2018/02/11 Python
Python迭代器与生成器用法实例分析
2018/07/09 Python
python特性语法之遍历、公共方法、引用
2018/08/08 Python
PyQt5内嵌浏览器注入JavaScript脚本实现自动化操作的代码实例
2019/02/13 Python
pyqt5实现登录界面的模板
2020/05/30 Python
django框架实现模板中获取request 的各种信息示例
2019/07/01 Python
pytorch 修改预训练model实例
2020/01/18 Python
jupyter notebook oepncv 显示一张图像的实现
2020/04/24 Python
html5唤起app的方法
2017/11/30 HTML / CSS
技校生自我鉴定范文
2013/09/26 职场文书
教育科研先进个人材料
2014/01/26 职场文书
成龙洗发水广告词
2014/03/14 职场文书
节约用电通知
2015/04/25 职场文书
承兑汇票延期证明
2015/06/23 职场文书
使用Html+Css实现简易导航栏功能(导航栏遇到鼠标切换背景颜色)
2021/04/07 HTML / CSS
Spring Boot 底层原理基础深度解析
2022/04/03 Java/Android