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 相关文章推荐
Mootools 1.2教程 Fx.Tween的使用
Sep 15 Javascript
读jQuery之八 包装事件对象
Jun 21 Javascript
基于jquery的loading 加载提示效果实现代码
Sep 01 Javascript
Ajax提交与传统表单提交的区别说明
Feb 07 Javascript
基于Jquery插件实现跨域异步上传文件功能
Apr 26 Javascript
JavaScript lodash常见用法系列小结
Aug 24 Javascript
JavaScript中数组slice和splice的对比小结
Sep 22 Javascript
jquery组件WebUploader文件上传用法详解
Oct 23 Javascript
实例讲解DataTables固定表格宽度(设置横向滚动条)
Jul 11 Javascript
在vue-cli搭建的项目中增加后台mock接口的方法
Apr 26 Javascript
使用VueCli3+TypeScript+Vuex一步步构建todoList的方法
Jul 25 Javascript
JS实现页面数据懒加载
Feb 13 Javascript
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 显示指定路径下的图片
2009/10/29 PHP
Session保存到数据库的php类分享
2011/10/24 PHP
PHP5中GD库生成图形验证码(有汉字)
2013/07/28 PHP
PHP Yii框架之表单验证规则大全
2015/11/16 PHP
php实现倒计时效果
2015/12/19 PHP
PHP信号量基本用法实例详解
2016/02/12 PHP
php分页查询mysql结果的base64处理方法示例
2017/05/18 PHP
php源码的安装方法和实例
2019/09/26 PHP
用ASP将SQL搜索出来的内容导出为TXT的代码
2007/07/27 Javascript
ie focus bug 解决方法
2009/09/03 Javascript
jQuery源码分析-04 选择器-Sizzle-工作原理分析
2011/11/14 Javascript
JS 获取select(多选下拉)中所选值的示例代码
2013/08/02 Javascript
jQuery zTree加载树形菜单功能
2016/02/25 Javascript
JavaScript事件处理的方式(三种)
2016/04/26 Javascript
JavaScript之事件委托实例(附原生js和jQuery代码)
2017/07/22 jQuery
利用node.js实现反向代理的方法详解
2017/07/24 Javascript
Element中的Cascader(级联列表)动态加载省\市\区数据的方法
2019/03/27 Javascript
vuex入门最详细整理
2020/03/04 Javascript
JavaScript实现简单计算器
2020/03/19 Javascript
python查找指定具有相同内容文件的方法
2015/06/28 Python
Flask框架的学习指南之制作简单blog系统
2016/11/20 Python
python系统指定文件的查找只输出目录下所有文件及文件夹
2020/01/19 Python
python db类用法说明
2020/07/07 Python
Pandas DataFrame求差集的示例代码
2020/12/13 Python
浅谈Html5页面打开app的一些思考
2020/03/30 HTML / CSS
美国马匹用品和马钉购物网站:State Line Tack
2018/08/05 全球购物
如何启动时不需输入用户名与密码
2014/05/09 面试题
大学老师推荐信
2014/02/25 职场文书
社区工作者感言
2014/03/02 职场文书
2014年大学庆元旦迎新年活动方案
2014/03/09 职场文书
警校毕业生自我评价
2014/04/06 职场文书
毕业生找工作求职信
2014/08/05 职场文书
竞选班干部演讲稿400字
2014/08/20 职场文书
办公室务虚会发言材料
2014/10/20 职场文书
2015入党自传书范文
2015/06/26 职场文书
廉洁自律承诺书2016
2016/03/25 职场文书