前言
一般而言,我看书中算法,写的顺序都是从小到大排序。当然,稍加改变代码就能实现从大到小。那么就默认从小到大(递增)的排序方式吧。
先从最简单的排序算法——冒泡排序开始吧
冒泡排序原理:
先把第一个数字抽出来与第二个数字相比,如果第一个数字大于第二个数字,那么它两交换位置,如果小于或等于那么顺序不变。同样的操作然后再从第二个数字与第三个数字相比。这样操作后,数组中最大的数字就确定好位置在数组的最后面 以上操作重复,那么就把第二大的数字确定下来,放到了数组中倒数第二的位置 那么要重复几次这种操作呢。数组中有几个数,就重复几次。
举例
给一个乱序的数组:[5,8,2,3]
第一次:[5,8,2,3]
从第1个数字开始: 5>8? no 不换位置 [5,8,2,3]
从第2个数字开始:8>2? yes 换位置 [5,2,8,3]
从第3个数字开始:8>3? yes 换位置 [5,2,3,8]
第二次:[5,2,3,8]
从第1个数字开始: 5>2? yes 换位置 [2,5,3,8]
从第2个数字开始:5>3? yes 换位置 [2,3,5,8]
从第3个数字开始:5>8? no 不换位置 [2,3,5,8]
第三次:[2,3,5,8]
从第1个数字开始: 2>3? no 不换位置 [2,3,5,8]
从第2个数字开始:3>5? no 不换位置 [2,3,5,8]
从第3个数字开始:5>8? no 不换位置 [2,3,5,8]
第四次:[2,3,5,8]
从第1个数字开始: 2>3? no 不换位置 [2,3,5,8]
从第2个数字开始:3>5? no 不换位置 [2,3,5,8]
从第3个数字开始:5>8? no 不换位置 [2,3,5,8]
小结:
数组有几个数,就要遍历几次。每次比对都从第一个数开始,两两比对,数值大的往后放。那么第一次遍历结果就将最大的数放在最后。每次遍历都是相同操作,自然就组成一个升序的数组。
- 遍历次数与数组的长度相等
- 内部比对的次数,因为不用自己和自己比,所以是长度-1。这从举例中也可看出。
代码
js代码
function bubbleSort(array) {
for (let i = 0; i < array.length; i++) {
for (let j = 0; j < array.length - 1; j++) {
if (array[j] > array[j + 1]) {
// 这是es6推出的解构语法,在数组中值交换时非常方便。
[array[j],array[j+1]]=[array[j+1],array[j]]
// 不然就需要一个临时变量来接
// let tem = array[j];
// array[j] = array[j + 1];
// array[j + 1] = tem;
}
}
}
return array;
}
const a = [5, 8, 2, 3];
const b = bubbleSort(a);
console.log(b);
ts 代码
function bubbleSort<T>(array:T[]){
for (let i = 0; i < array.length; i++) {
for (let j = 0; j < array.length - 1; j++) {
if (array[j] > array[j + 1]) {
[array[j],array[j+1]]=[array[j+1],array[j]]
}
}
}
return array;
}
优化
我们观察发现。
第一次比较时已经将最大的数值8找出,放在了数组的最后。此时 i=0
第二次比较时,与最后8的数值就没有必要比了,可以减少一次比较。并且将第二大的数值5找出放在了数组倒数第二的位置上 此时 i=1
第三次比较时,最大与第二大的数值排好了,就不要再与它们比了,减少两次比较,并且将第三大的数值3找出放在了数组倒数第三的位置上 此时 i=2
第四次比较时,最大与第二大与第三大的数值排好了,就不要再与它们比了,减少三次比较,并且将第四大的数值2找出放在了数组倒数第四的位置上 此时 i=3
等一下,再想想,总共4个数,第三次比较时,已经确定好了最大三个数的位置。第四个数就是最小的数值,它的位置就正好在第一个,所以第四次比较就没必要了。
所以要修改两处。
function bubbleSort(array) {
// 第一处修改,最后一次的遍历没必要,因为剩余的数值都从小到大排好了,最小的数值就正好排在第一位上
for (let i = 0; i < array.length-1; i++) {
// 第一处修改 array.length-1还要减去i,这样每一次外层的遍历都会少i次
for (let j = 0; j < array.length - 1-i; j++) {
if (array[j] > array[j + 1]) {
// 这是es6推出的解构语法,在数组中值交换时非常方便。
[array[j],array[j+1]]=[array[j+1],array[j]]
// 不然就需要一个临时变量来接
// let tem = array[j];
// array[j] = array[j + 1];
// array[j + 1] = tem;
}
}
}
return array;
}
const a = [5, 8, 2, 3];
const b = bubbleSort(a);
console.log(b);