之前我們已經(jīng)聊過 冒泡排序
商乎,但是當我們的元素列表中如果存在了一批已經(jīng)排好序的數(shù)據(jù)羊苟,冒泡排序還是會堅挺的執(zhí)行下去寂曹。造成資源的浪費,針對這種情況我們來優(yōu)化一下衬潦。
如需要對以下數(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
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]
第 3 次
- [2
3
1 4 5 6 7 8 9 10] - [2 1
3
4 5 6 7 8 9 10]
第 4 次
- [1
2
3 4 5 6 7 8 9 10]
代碼實現(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)
//對比兩個相鄰元素
if numbers[j] > numbers[j+1] {
//如果如果第一個比第二個大镀岛,就交換它們的位置弦牡。 【順序】
//倒序反之:如果第一個比第二個小,就交換它們的位置漂羊。
numbers[j+1], numbers[j] = numbers[j], numbers[j+1]
//記錄最后交換的位置驾锰。因為從零開始,所以加1
lastSwap = j+1
}
fmt.Printf("%d. %v\n", j+1, numbers)
}
fmt.Println("")
//如果長度和最后位置不匹配走越,意味著還有數(shù)據(jù)進行交換稻据。
if length!=lastSwap {
length = lastSwap //交換位置。
i=-1 //重置外層循環(huán),因為接下來會有`i++`捻悯,所以設置為 `-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++) {
//對比兩個相鄰元素
if ($numbers[$j] > $numbers[$j + 1]) {
//如果如果第一個比第二個大,就交換它們的位置淤毛。 【順序】
//倒序反之:如果第一個比第二個小今缚,就交換它們的位置。
list($numbers[$j + 1], $numbers[$j]) = array($numbers[$j], $numbers[$j + 1]);
$last = $len;
}
}
//如果長度和最后位置不匹配低淡,意味著還有數(shù)據(jù)進行交換姓言。
if ($last != $len) {
$len = $last;
$i = -1;//重置外層循環(huán),因為接下來會有`i++`蔗蹋,所以設置為 `-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++) {
//對比兩個相鄰元素
if (numbers[j] > numbers[j + 1]) {
//如果如果第一個比第二個大何荚,就交換它們的位置。 【順序】
//倒序反之:如果第一個比第二個小猪杭,就交換它們的位置餐塘。
//解構(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):
"""
如果如果第一個比第二個大,就交換它們的位置皂吮。 【順序】
倒序反之:如果第一個比第二個小戒傻,就交換它們的位置。
"""
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]
微信搜索:小碼俠