冒泡排序的基本思想,就是相邻的两个数字进行比较,如果它们的顺序错误,就把它们交换过来。什么是顺序错误呢?比如我们按从大到小进行排列,那么应该是大的数在前面,小的数在后面,两个数如果是45,98这么排列,它们就是顺序错误,我们就要把它们交换过来,变为45,98;
现在我们就按照上面的基本思想,对5个数12, 35, 99, 8, 100进行降序排列。
1, 首先比较第1个数和第2个数:12,35,由于是降序排列,越小的数应该越在后面, 而在这里12 比35小,却排在了前面, 不符合要求,就是顺序错误,我们要把它们交换过来,经过交换之后,变成了 35, 12, 99, 8, 100;
2, 现在再比较第2个数和第3个数: 12,99,由于12 还是小于99, 确排在前面,我们仍要调换它们的位置, 调换之后为35, 99, 12, 8, 100;
3, 再比较第3个数和第4个数; 12, 8: 12 > 8 , 符合小的在后面的原则,不用调换位置。
4, 最后比较第4个数和第5个数: 8 和100, 调换它们的位置 35, 99, 12, 100, 8;
经过这4次比较,我们把最小的数字8找出来了,并放到了最后。但是仅仅找出了一个最小的数。我们还是需要进行排序,还是要按照上面的两两比较方法,
现在再进行一次排序:
1,比较第1个数和第2个数:35, 99, 由于35 < 99, 不符合越小的数越在后面的原则,所以交换它们的位置: 99, 35, 12, 100, 8;
2, 比较第2个和第3个数:35,12; 可以看到,它们不用交换位置
3, 比较第3个数和第4个数: 12, 100,需要交换它们的位置 99, 35, 100, 12, 8;
注意,这里就不用再去比较第4位和第5位数了,因为在上面的第一次比较中,8已经是最小的数了。
这里只经过3个比较,找出的第二小的数。
接着进行排序, 还是要两两比较,找出第三小的数
1, 比较第1个数和第2个数: 99,35, 不需要交换它们的位置。
2, 再比较第2个数和第3个数: 35, 100, 需要交换它们的位置 99,100, 35,12,8
经过2个比较,我们找出了第3小的数,35;
还是需要进行一个比较,找出第4小的数字,
只需要比较第1个数和第2个数, 99,100,交换它们的位置。100,99,35, 12, 8
这里只需要比较1次,就可以完成任务了。
最终排序完成。100,99,35, 12, 8
上面的排序过程,我们发现大的比较,一共发生了四次,每一次,我们称之为一趟。而每一趟只确定一个数进行归位。
现在对上面的过程进行抽象一下: 我们一共5个数,共进行了4趟比较, 也就是说,如果我们有n个数, 我们要经历n-1趟比较。现在再看每一趟中的内部比较。
在第一趟中,我们经过了4次比较,在第二趟中,我们经过了3次比较,
在第三趟中,我们经过了2次比较,在第四趟中,我们经过了1次比较
可以发现 趟数 + 比较次数 = 总共的个数。我们确定了趟数i, 用总数n 减去趟数就可以了。
现在就可以用程序写一下。由于每次都是两两比较,所以我们要确定一个变量i, 比较完一次后,让它自动加1,以便进行下次比较,这就是循环。当然我们还要确定多少个数字,以便确认比较多少次。长度加上循环, 用数组是最好不过的了。
function bubbleSort (arr) { let newArray = arr.slice(); // 函数式编程的思想,不要对外部的变量进行改变。 let n = newArray.length; // 数组的长度,从而确定比较多少趟 // 冒泡排序核心,首先要比较n- 1趟,因为每一趟只能确定一个数字 for(let i = 0; i< n -1; i++) { for(let j =0; j< n - i; j++) {// 每一趟内部进行两两比较,而比较的次数就是 n -i // 如果顺序错误,就交换它们的位置 if(newArray[j] < newArray[j + 1]) { let temp = newArray[j]; newArray[j] = newArray[j+1]; newArray[j+1] = temp; } } } return newArray; }
把 我们上面排序的5个数放入数组中,然后传入到bubbleSort 函数中
let array = [12, 35, 99, 8, 100]; console.log("排序前的数组:" + array); console.log("排序后的数组:" +bubbleSort(array));
结果如下,排序没有问题