冒泡的意义无非就是一次次的寻找最小或最大值,一次冒泡将一个元素排序到应在的位置,比如第一次冒泡可以将最小值放在第一个位置,以此类推,那么期间就会出现多次的重复交换,是一种极大地浪费。基于此,笔者对其进行了一定的优化。
竟然每次循环都是从头到尾的遍历去查找最大或最小值,那么为什么不干脆一起做了呢?如果每次的循环只是寻找最大最小值的索引,并且按照预设的位置对号入座不就可以了吗?比如预设索引为0为最小值的位置,数组的最后一位存放的是最大值,以此类推索引为1是次小值,倒数第二位就是次大值。于是第一次循环我们找到了最大最小值,那么这两个位置就已经占好了位置,所以最小值的遍历索引+1,最大值索引-1,那么每一次查找又会相应地调整最终循环的次数,即每次都会减少两次的内外层循环次数。随着循环的深入,外层循环只是遍历了数组的一半即可完成排序。
package main
import "fmt"
func main() {
arr :=[]int{10,23,14,3,1,2,6,8,9,12,13,56,89,1}
// 设最大值的位置为数组的最后一位
maxIndex := len(arr)-1
// 记录最大值位置的索引(任意值)
temp := maxIndex
for i:=0;i<maxIndex;i++{
// 将当前值预设成最小值
min := arr[i]
// 将最大索引值预设成最大值
max := arr[maxIndex]
minIndex:=i
for j:=i+1;j<=maxIndex;j++ {
// 在一次循环中查找最大值与最小值
if min>arr[j]{
// 记录最小值的以及索引位置
min = arr[j]
minIndex = j
}
if max<arr[j]{
// 记录最大值以及索引位置
max = arr[j]
temp = j
}
}
// 一次循环都会得到当前查找值中的最小值与最大值
if minIndex != i{ // 如果最小值的索引不是当前值,则进行一次交换
arr[i],arr[minIndex] = arr[minIndex],arr[i]
}
if temp != maxIndex{ // 如果查找到的最大值的索引位置与预设的最大值索引位置不一致,则进行交换
arr[temp],arr[maxIndex] = arr[maxIndex],arr[temp]
// 将最大值的索引调整为次最大值
maxIndex --
}
}
fmt.Println(arr)
}