博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用js写插入排序和选择排序
阅读量:5903 次
发布时间:2019-06-19

本文共 3218 字,大约阅读时间需要 10 分钟。

我觉得作为前端学学算法也是有益处的吧,所以今天就先来讲讲最基础的排序算法。提升我们程序员的内功~

插入排序

插入排序是n^2的基础排序方法,大致思想是假设一个数组的前n个元素已经有序,然后考虑把第n+1个未排序的元素给插入到有序数组中去。现将n+1和第n个元素比较,如果n+1比n小,那么就交换一下位置。之后我们要排序的元素就在n这个位置上了,接着我们继续比较n和第n-1个元素的大小。如此反复,直到我们要插入的元素找到适合他的位置。

下面来示范一下
6--7--8--9--3--1--4--6--3--8--9--5
6--7--8--9已经有序,我们要插入的元素是n=4这个元素3。比较9和3的大小,9比3大。交换一下位置
6--7--8--3--9,就变成了这个样子。接着比较8和3的大小,8比3大,交换一下位置
6--7--3--8--9,继续比较7和3的大小,7比3大,交换一下位置
6--3--7--8--9,继续比较6和3的大小,6比3大,交换一下位置
3--6--7--8--9。到这里循环结束,就已经排好序了。接着比较第n=5的元素1应该插入的位置,如此往复就把数组给排好了序了。
一下是代码。

//写一个随机生成数组的函数function randomArr(count) {  var arr = []  for (var i = 0; i < count; i++) {    var number = Math.ceil(Math.random() * 5000)    arr.push(number)  }  return arr}// 交换元素位置的函数function swap(arr, i, j) {  var temp = arr[i]  arr[i] = arr[j]  arr[j] = temp}var arr = randomArr(5000)// 插入排序函数function insertionSort(arr) {    var length = arr.length    // 第0个元素默认就是有序的,因为只有一个元素,所以从第一个元素开始。arr[i]就是要插入的那个元素    for (var i = 1; i < length; i++) {        // 从第i-1个元素往前都是已经排好序的元素。所以最后一个开始往前比较        for (var j = i - 1; j >= 0; j--) {            // 这里的j+1等于i这个元素。也就是arr[i] === arr[j+1]            if (arr[j] > arr[j + 1]) {                swap(arr, j + 1, j)            } else {                break            }        }    }    return arr}insertionSort(arr)

由于是两层for循环,所以它的时间复杂度是n^2级别的。

到这里其实还没有完,插入排序还是有可以优化的地方的。现在的这个插入排序函数要swap频繁的交换位置,我们可以这样

function insertionSort(arr) {    var length = arr.length    // 第0个元素默认就是有序的,因为只有一个元素,所以从第一个元素开始。arr[i]就是要插入的那个元素    for (var i = 1; i < length; i++) {        // **用一个变量保存要插入的元素**        var value = arr[i]        // 从第i-1个元素往前都是已经排好序的元素。所以最后一个开始往前比较        for (var j = i - 1; j >= 0; j--) {            // 这里的j+1等于i这个元素。也就是arr[i] === arr[j+1]            if (arr[j] > value) {                // 如果比要插入的元素大,把值arr[j]往右移一位                arr[j+1] = arr[j]                // 边界条件,直到j等于0的时候终止循环,将value赋给arr[0],结束循环                if (j === 0){arr[j] = value; break}            } else {                // 否则把value赋给arr[j]循环结束                arr[j] = value                break                }        }    }    return arr}

虽然插入排序是n^2级别的算法,但是在一个近乎有序的数组里去实现插入排序,那么他的效率会变的非常高。

因为插入排序可以提前break掉内层循环。

有兴趣可以写一个生成近乎有序数组的函数去实验一下。

// 近乎有序数组function nearlySorted(arr) {  return arr}

选择排序

选择排序就是在循环中不停的选择最小的元素,然后交换位置。

下面来示范一下
6--7--8--9--3--1--4--6--3--8--9--5
找到数组中最小的元素1,然后记录1的位置是5。接着交换位置变成
1--7--8--9--3--6--4--6--3--8--9--5
接着在剩下的数组里7--8--9--3--6--4--6--3--8--9--5找到最小的元素3,记录下它的下标位置是4,然后交换位置变成
1--3--8--9--7--6--4--6--3--8--9--5。如此往复直到排好序。

function randomArr(count) {  var arr = []  for (var i = 0; i < count; i++) {    var number = Math.ceil(Math.random() * 5000)    arr.push(number)  }  return arr}function swap(arr, i, j) {  var temp = arr[i]  arr[i] = arr[j]  arr[j] = temp}var arr = randomArr(5000)function selectionSort(arr) {  var length = arr.length  var value, pos  for (var i = 0; i < length; i++) {    value = arr[i]    pos = i    for (var j = i; j < length; j++) {      var cur = arr[j]      if (value > cur) {        value = cur        pos = j      }    }    swap(arr, i, pos)  }  return arr}selectionSort(arr)

到此两个基础排序就实现了。总结一下,插入排序优于选择排序。

插入排序可以提前终止内层循环,如果数组近乎有序,那么效率会很高。而选择排序无法提前终止循环。

不过最好的排序算法还是nlogn级别的算法。如归并排序和快速排序。
我的写的不是最好的,仅仅是解释概念,有兴趣的同学可以自己写一个更好的插入排序和选择排序。

转载地址:http://dyupx.baihongyu.com/

你可能感兴趣的文章
CCNA- 距离矢量路由协议学习
查看>>
企业实践用户邮箱导入/导出(第2部分)
查看>>
如何学习Linux命令-初级篇
查看>>
从Oracle Public Yum为Oracle Linux建立本地的Yum源
查看>>
静态路由和默认路由
查看>>
关于阿里开发者招聘节 |这5道笔试真题 你会吗!???
查看>>
C#的异常处理机制
查看>>
vsftp:500 OOPS: could not bind listening IPv4 sock
查看>>
Linux安装BTCPayServer并设置比特币BTC和Lightning支付网关
查看>>
mysql安装,远程连接,以及修改密码
查看>>
Mybatis查询返回Map类型数据
查看>>
java的深拷贝与浅拷贝
查看>>
程序员如何提高工作效率
查看>>
promise
查看>>
将Java应用部署到SAP云平台neo环境的两种方式
查看>>
数据批量导入Oracle数据库
查看>>
调用lumisoft组件发邮件 不需要身份验证 不需要密码
查看>>
DW 正则
查看>>
抓屏原理
查看>>
UNIX网络编程读书笔记:TCP输出、UDP输出和SCTP输出
查看>>