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 相关文章推荐
javascript web对话框与弹出窗口
Feb 22 Javascript
使用自定义setTimeout和setInterval使之可以传递参数和对象参数
Apr 24 Javascript
JS 控制小数位数的实现代码
Aug 02 Javascript
jquery序列化表单以及回调函数的使用示例
Jul 02 Javascript
javascript实现起伏的水波背景效果
May 16 Javascript
WdatePicker.js时间日期插件的使用方法
Jul 26 Javascript
webpack 2.x配置reactjs基本开发环境详解
Aug 08 Javascript
详谈js原型继承的一些问题
Sep 06 Javascript
react router 4.0以上的路由应用详解
Sep 21 Javascript
vuejs实现ready函数加载完之后执行某个函数的方法
Aug 31 Javascript
微信小程序实现吸顶特效
Jan 08 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简单判断文本编码的方法
2015/07/30 PHP
PHP中SSO Cookie登录分析和实现
2015/11/06 PHP
php简单获取复选框值的方法
2016/05/11 PHP
Laravel如何友好的修改.env配置文件详解
2017/06/07 PHP
任意位置显示html菜单
2007/02/01 Javascript
jQuery 学习入门篇附实例代码
2010/03/16 Javascript
jQuery获取和设置表单元素的方法
2014/02/14 Javascript
js继承call()和apply()方法总结
2014/12/08 Javascript
Angularjs基础知识及示例汇总
2015/01/22 Javascript
jquery中change()用法实例分析
2015/02/06 Javascript
JQuery记住用户名密码实现下次自动登录功能
2015/04/27 Javascript
js实现浏览本地文件并显示扩展名的方法
2015/08/17 Javascript
JS实现在状态栏显示打字效果完整实例
2015/11/02 Javascript
jQuery基于扩展实现的倒计时效果
2016/05/14 Javascript
AngularJs $parse、$eval和$observe、$watch详解
2016/09/21 Javascript
NODE.JS跨域问题的完美解决方案
2016/10/20 Javascript
简单实现jQuery弹幕效果
2017/05/06 jQuery
使用JS中的Replace()方法遇到的问题小结
2017/10/20 Javascript
JavaScript登录验证基础教程
2017/11/01 Javascript
微信小程序switch组件使用详解
2018/01/31 Javascript
Angular2使用SVG自定义图表(条形图、折线图)组件示例
2019/05/10 Javascript
微信小程序实现左侧滑动导航栏
2020/04/08 Javascript
利用JS如何获取form表单数据
2019/12/19 Javascript
python获得图片base64编码示例
2014/01/16 Python
Python实现简单拆分PDF文件的方法
2015/07/30 Python
两个命令把 Vim 打造成 Python IDE的方法
2016/03/20 Python
python3爬取淘宝信息代码分析
2018/02/10 Python
Python 忽略warning的输出方法
2018/10/18 Python
python/sympy求解矩阵方程的方法
2018/11/08 Python
python-itchat 统计微信群、好友数量,及原始消息数据的实例
2019/02/21 Python
Python爬取视频(其实是一篇福利)过程解析
2019/08/01 Python
高中的自我鉴定
2013/12/16 职场文书
房产销售经理职责
2013/12/20 职场文书
入党函调证明材料
2014/12/24 职场文书
证劵公司反洗钱宣传活动总结
2015/05/08 职场文书
Nginx使用ngx_http_upstream_module实现负载均衡功能示例
2022/08/05 Servers