码迷,mamicode.com
首页 > 编程语言 > 详细

让冒泡排序的对比次数更少(js实例)

时间:2018-03-07 10:28:53      阅读:222      评论:0      收藏:0      [点我收藏+]

标签:移动   span   color   对比   比较   一个   log   break   efi   

一般网上的冒泡排序例子是这样的:

function bubbleSort(arr) {
  let i = arr.length;
    let tempExchangVal = undefined;
    while (i > 0) {
        for (let j = 0; j < i - 1; j++) {
       num++;
            if (arr[j] > arr[j + 1]) {
                tempExchangVal = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = tempExchangVal;
            }
        }
        i--;
    }
    return arr;
}
 
let arr = [3, 2, 4, 9, 5, 7, 1, 6, 8];
let num = 0; // 对比的次数变量
let arrSorted = bubbleSort(arr);
console.log(arrSorted); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(num); // 36

思路就是一个数组里有几个数字就循环几次取出索引来利用(为了称呼方便,称此次循环叫做大循环),然后将被取出的循环数字再带入数组循环一遍找出当前循环里最大的数(为了称呼方便,称此次循环叫做小循环),最大的数将被移到数组最尾部,并且使得在这过程中的数字位置能够调整规范。小循环后再将 i 变量减一,用来进行下一个大循环并且使小循环不会循环到之前已经移到数组最尾部的数字。

但这种写法有个弊端就是如果上次循环已经对比整理了前后数组,这次循环还会再进行对比,不过不会再整理,这样算是多做了无用功。举个例子:上次循环已经把最前面的3个数字3、2、4对比排列成了2、3、4,这次循环依然还会再对比一次2和3跟3和4。这其实是可以不用对比的,因为之前已经对比排列过了,再对比一次只能算是多此一举,像上面这种,已经对比了36次,其中有很大一部分是重复的对比。

后来,我自己想出了另一种对比更少的算法:

let oldArr = [3, 2, 4, 9, 5, 7, 1, 6, 8]
let num = 0 // 对比次数的变量

function bubbleSort (arr, index = 0) {
  let indexAdd1 = index + 1
  for (let i = 0; indexAdd1 > 0; indexAdd1--) {
    let compareArr = [arr[indexAdd1 - 1], arr[indexAdd1]]
    num++
    if (compareArr[0] > compareArr[1]) {
      arr[indexAdd1 - 1] = compareArr[1]
      arr[indexAdd1] = compareArr[0]
    } else {
      break
    }
  }

  if (index < arr.length - 1) {
    return bubbleSort(arr, index + 1)
  } else {
    return arr
  }
}

let sortArr = bubbleSort(oldArr)
console.log(sortArr) // [1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(num) // 19

我自己的思路是这样:循环一遍所有索引(大循环),每次循环执行函数时都会把上次循环处理过的数组带入进去,直到最后一个索引将最后处理的数组返回回去,每次进行大循环时,都会将要循环处理的索引和它的下一位比较,如果下一位比处理的索引大那就没问题,不进行操作,如果比它小就和其调换,然后再往后面进行对比调换,直到遇到一个比它还小的数才停止对比调换(小循环)。

例如:索引[0]是3,它的下一位是2,3比2大所以调换位置,调换后2后面没有索引了,所以没有再执行对比调换;由于上个循环有调换索引了,现在索引[1]还是3,它的下一位索引[2]是4,3比4小索引不调换;接着索引[2]是4,下一位索引[3]是9,4比9小所以也没调换位置;索引[3]是9,下一个索引[4]是5,9比5大那就必须调换位置了,现在索引[3]是5而索引[4]是9了,然后再将索引[3]和后面的索引对比,现在对比索引[2],索引[2]是4,比5小,所以无需再调换,因为之前已经按大小排序了,所以索引[2]后面的数肯定比索引[2]小,那也就无需再对比了,这样就可以节省几步了,而这几步也是第一个写法时重复的步骤;接着再从索引[4]开始对比,对比索引[5],然后按照结果看是要移动位置还是不用;索引[5]再对比索引[6],索引[6]再对比索引[7]。。。直到最后一位索引索引。

两种写法如果数组元素较少对比的次数可能不会差多少,不过如果数组元素比较多第一种算法就会进行很多重复的比较了。

让冒泡排序的对比次数更少(js实例)

标签:移动   span   color   对比   比较   一个   log   break   efi   

原文地址:https://www.cnblogs.com/keka1996/p/8476856.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!