之前我們已經(jīng)聊過 冒泡排序 ,但是當(dāng)我們的元素列表中如果存在了一批已經(jīng)排好序的數(shù)據(jù),冒泡排序還是會(huì)堅(jiān)挺的執(zhí)行下去。造成資源的浪費(fèi),針對(duì)這種情況我們來優(yōu)化一下。
如需要對(duì)以下數(shù)據(jù)排序:
{5, 2, 4, 3, 1, 6 ,7 ,8 ,9 ,10 }
原始冒泡排序效果
第 1 次
- [2 5 4 3 1 6 7 8 9 10]
- [2 4 5 3 1 6 7 8 9 10]
- [2 4 3 5 1 6 7 8 9 10]
- [2 4 3 1 5 6 7 8 9 10]
- [2 4 3 1 5 6 7 8 9 10]
- [2 4 3 1 5 6 7 8 9 10]
- [2 4 3 1 5 6 7 8 9 10]
- [2 4 3 1 5 6 7 8 9 10]
- [2 4 3 1 5 6 7 8 9 10]
第 2 次
- [2 4 3 1 5 6 7 8 9 10]
- [2 3 4 1 5 6 7 8 9 10]
- [2 3 1 4 5 6 7 8 9 10]
- [2 3 1 4 5 6 7 8 9 10]
- [2 3 1 4 5 6 7 8 9 10]
- [2 3 1 4 5 6 7 8 9 10]
- [2 3 1 4 5 6 7 8 9 10]
- [2 3 1 4 5 6 7 8 9 10]
第 3 次
- [2 3 1 4 5 6 7 8 9 10]
- [2 1 3 4 5 6 7 8 9 10]
- [2 1 3 4 5 6 7 8 9 10]
- [2 1 3 4 5 6 7 8 9 10]
- [2 1 3 4 5 6 7 8 9 10]
- [2 1 3 4 5 6 7 8 9 10]
- [2 1 3 4 5 6 7 8 9 10]
第 4 次
從第四次開始,排序已經(jīng)沒有效果了。
- [1 2 3 4 5 6 7 8 9 10]
- [1 2 3 4 5 6 7 8 9 10]
- [1 2 3 4 5 6 7 8 9 10]
- [1 2 3 4 5 6 7 8 9 10]
- [1 2 3 4 5 6 7 8 9 10]
- [1 2 3 4 5 6 7 8 9 10]
第 5 次
- [1 2 3 4 5 6 7 8 9 10]
- [1 2 3 4 5 6 7 8 9 10]
- [1 2 3 4 5 6 7 8 9 10]
- [1 2 3 4 5 6 7 8 9 10]
- [1 2 3 4 5 6 7 8 9 10]
第 6 次
- [1 2 3 4 5 6 7 8 9 10]
- [1 2 3 4 5 6 7 8 9 10]
- [1 2 3 4 5 6 7 8 9 10]
- [1 2 3 4 5 6 7 8 9 10]
第 7 次
- [1 2 3 4 5 6 7 8 9 10]
- [1 2 3 4 5 6 7 8 9 10]
- [1 2 3 4 5 6 7 8 9 10]
第 8 次
- [1 2 3 4 5 6 7 8 9 10]
- [1 2 3 4 5 6 7 8 9 10]
第 9 次
- [1 2 3 4 5 6 7 8 9 10]
優(yōu)化后效果
第 1 次
- [2
54 3 1 6 7 8 9 10] - [2 4
53 1 6 7 8 9 10] - [2 4 3
51 6 7 8 9 10] - [2 4 3 1
56 7 8 9 10] - [2 4 3 1 5 6 7 8 9 10]
- [2 4 3 1 5 6 7 8 9 10]
- [2 4 3 1 5 6 7 8 9 10]
- [2 4 3 1 5 6 7 8 9 10]
- [2 4 3 1 5 6 7 8 9 10]
第 2 次
- [2
43 1 5 6 7 8 9 10] - [2 3
41 5 6 7 8 9 10] - [2 3 1
45 6 7 8 9 10]
第 3 次
- [2
31 4 5 6 7 8 9 10] - [2 1
34 5 6 7 8 9 10]
第 4 次
- [1
23 4 5 6 7 8 9 10]
代碼實(shí)現(xiàn)
package main
import "fmt"
func main() {
//聲明數(shù)組
numbers := []int{5, 2, 4, 3, 1, 6, 7, 8, 9, 10}
length := len(numbers)
lastSwap := length
count:=0
//構(gòu)建遍歷循環(huán)
for i := 0; i < length-1; i++ {
fmt.Printf("**第 %d 次**\n\n", count+1)
count++
for j := 0; j < length-i-1; j++ {
//fmt.Println(i,j)
//對(duì)比兩個(gè)相鄰元素
if numbers[j] > numbers[j+1] {
//如果如果第一個(gè)比第二個(gè)大,就交換它們的位置。 【順序】
//倒序反之:如果第一個(gè)比第二個(gè)小,就交換它們的位置。
numbers[j+1], numbers[j] = numbers[j], numbers[j+1]
//記錄最后交換的位置。因?yàn)閺牧汩_始,所以加1
lastSwap = j+1
}
fmt.Printf("%d. %v\n", j+1, numbers)
}
fmt.Println("")
//如果長度和最后位置不匹配,意味著還有數(shù)據(jù)進(jìn)行交換。
if length!=lastSwap {
length = lastSwap //交換位置。
i=-1 //重置外層循環(huán),因?yàn)榻酉聛頃?huì)有`i++`,所以設(shè)置為 `-1`
}
}
}
PHP
<?php
$numbers = array(5, 2, 4, 3, 1, 6, 7, 8, 9, 10);
$len = count($numbers);
$last = $len;
//構(gòu)建遍歷循環(huán)
for ($i = 0; $i < $len - 1; $i++) {
for ($j = 0; $j < $len - $i - 1; $j++) {
//對(duì)比兩個(gè)相鄰元素
if ($numbers[$j] > $numbers[$j + 1]) {
//如果如果第一個(gè)比第二個(gè)大,就交換它們的位置。 【順序】
//倒序反之:如果第一個(gè)比第二個(gè)小,就交換它們的位置。
list($numbers[$j + 1], $numbers[$j]) = array($numbers[$j], $numbers[$j + 1]);
$last = $len;
}
}
//如果長度和最后位置不匹配,意味著還有數(shù)據(jù)進(jìn)行交換。
if ($last != $len) {
$len = $last;
$i = -1;//重置外層循環(huán),因?yàn)榻酉聛頃?huì)有`i++`,所以設(shè)置為 `-1`
}
}
print_r($numbers);
/*
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
[6] => 7
[7] => 8
[8] => 9
[9] => 10
)
*/
JS
let numbers = [5, 2, 4, 3, 1, 6, 7, 8, 9, 10];
let len = numbers.length;
let last = len;
//構(gòu)建遍歷循環(huán)
for (let i = 0; i < len - 1; i++) {
for (let j = 0; j < len - i - 1; j++) {
//對(duì)比兩個(gè)相鄰元素
if (numbers[j] > numbers[j + 1]) {
//如果如果第一個(gè)比第二個(gè)大,就交換它們的位置。 【順序】
//倒序反之:如果第一個(gè)比第二個(gè)小,就交換它們的位置。
//解構(gòu)交換位置
[numbers[j + 1], numbers[j]] = [numbers[j], numbers[j + 1]];
last = j + 1;
}
}
if (last != len) {
len = last;
i = -1;
}
}
console.log(numbers);
// [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
Python
# -*- coding: UTF-8 -*-
numbers = [5, 2, 4, 3, 1, 6, 7, 8, 9, 10]
length = len(numbers)
last = length
while 1 == 1:
swapFlag = False # 記錄是否交換過
for i in range(length - 1):
for j in range(length - i - 1):
"""
如果如果第一個(gè)比第二個(gè)大,就交換它們的位置。 【順序】
倒序反之:如果第一個(gè)比第二個(gè)小,就交換它們的位置。
"""
if numbers[j] > numbers[j + 1]:
numbers[j], numbers[j + 1] = numbers[j + 1], numbers[j]
last = j + 1
swapFlag = True
if length != last:
length = last
break
if not swapFlag: # 已經(jīng)沒有數(shù)據(jù)可以交換了。直接退出。
break
print(numbers)
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
微信搜索:小碼俠

長按二維碼關(guān)注我們