1 )version 1 初始版本
function bubbleSort(nums: number[]) {
const len :number = nums.length;
for(let i: number = 0; i < len; i++) {
for(let j: number = 0; j < len - 1 - i; j++) {
if(nums[j] > nums[j + 1]) {
const tmp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = tmp;
}
}
}
}
const list: number[] = [5, 4, 3, 2, 1];
bubbleSort(list);
console.log(list); // [1, 2, 3, 4, 5]
2 ) version 2 ES6 做两数交换 优化版
function bubbleSort(nums: number[]) {
const len :number = nums.length;
for(let i: number = 0; i < len; i++) {
for(let j: number = 0; j < len - 1 - i; j++) {
if(nums[j] > nums[j + 1]) {
[nums[j], nums[j + 1]] = [nums[j + 1], nums[j]];
}
}
}
}
const list: number[] = [5, 4, 3, 2, 1];
bubbleSort(list);
console.log(list); // [1, 2, 3, 4, 5]
3 ) version 3 冒泡排序,提前终止版
function bubbleSort(nums: number[]) {
let len: number = nums.length;
let sorted: boolean = false; // 哨兵变量
while(!sorted) {
sorted = true; // 提前终止标识
for(let i: number = 0; i < len - 1; i++) {
if(nums[i] > nums[i + 1]) {
[nums[i], nums[i + 1]] = [nums[i + 1], nums[i]];
sorted = false;
}
}
// 如果经过上面一轮 sorted仍为true,没有变为false, 说明已经整体已经有序,可以提前终止了
len --;
}
}
const list: number[] = [5, 4, 3, 2, 1];
bubbleSort(list);
console.log(list); // [1, 2, 3, 4, 5]
4 )version 4 冒泡排序,跳跃版
function bubbleSort(nums: number[]) {
const len: number = nums.length;
let k: number = len - 1; // 跳跃标识
let last: number = 0; // 内层循环标识
let i: number = 0;
// 第一层循环表示经过n-1趟扫描即可,每比较一趟,问题规模缩小1级,第一层循环次数必须不变 n-1 次
while(i < len - 1) {
// 第二层循环表示每一趟进行两两逐个比较,找到最大的元素
for(let j: number = 0; j < k; ++j) {
// 当前元素和后一个元素进行比较,若逆序
if(nums[j] > nums[j+1]) {
// 则交换
[nums[j], nums[j + 1]] = [nums[j +1], nums[j]];
// 更新交换的位置
last = j;
}
}
// 在一层循环之后跳跃到最后交换的那个地方,这样的话,在k的位置,后面如果是有序,就可以直接跳过了
k = last;
++i;
}
}
const list: number[] = [5, 4, 3, 2, 1];
bubbleSort(list);
console.log(list); // [1, 2, 3, 4, 5]
5 )version 5 冒泡排序,提前终止+跳跃版
function bubbleSort(nums: number[]) {
const len: number = nums.length;
let k: number = len - 1; // 跳跃标识
let last: number = 0; // 内层循环标识
let i: number = 0; // 最外层循环标识
let sorted: boolean = false; // 哨兵变量
// 第一层循环表示经过n-1趟扫描即可,每比较一趟,问题规模缩小1级,第一层循环次数必须不变 n-1 次
while(i < len - 1 && !sorted) {
sorted = true;
// 第二层循环表示每一趟进行两两逐个比较,找到最大的元素
for(let j: number = 0; j < k; ++ j) {
// 当前元素和后一个元素进行比较,若逆序
if(nums[j] > nums[j + 1]) {
// 则交换
[nums[j], nums[j+1]] = [nums[j+1], nums[j]];
// 更新交换的位置
last = j;
sorted = false;
}
}
// 在一层循环之后跳跃到最后交换的那个地方,这样的话,在k的位置,后面如果是有序,就可以直接跳过了
k = last;
++i;
}
}
const list: number[] = [5, 4, 3, 2, 1];
bubbleSort(list);
console.log(list); // [1, 2, 3, 4, 5]