选择排序为在冒泡排序的基础上进行优化的一种排序算法,每次遍历只进行一次元素交换。
为了实现只进行一次交换:
- 那么需要在遍历中寻找出待排序元素中的最大值;
- 在遍历完后,把最大值放到正确的位置上。
和冒泡排序一样,第一次遍历后,最大元素处于正确的位置上;第二次遍历后,第二大的原始处于正确的位置上;以此类推。 具体排序过程如下图所示(箭头表示交换位置):
- 第一轮遍历时,发现最大的数为10,所以把10与最后面的数字交换位置,使得最大的数处于正确的位置上;
- 第二轮遍历时,待排序的元素里最大的数为5且已处于正确的位置,无需交换;
- 第三轮遍历时,待排序的元素里最大的数为3,需要把3放到正确的位置上。 至此,切片数组已排序完毕。
时间复杂度:O(n²)
从上面的排序过程中,给n个元素的切片数值选择排序需要经过n-1此遍历,然后每次遍历的比较次数依次为n-1、n-2、n-3、...、2、1,所以是1+2+3+...+n-2+n-1的和,即½n²-½n,即O(n²)。
但是每次遍历只需要交换一次,相比冒泡排序,选择排序减少了交换次数,所以较冒泡排序更快一点。 使用Golang实现的选择排序算法代码如下:
package main
import "fmt"
func selectSort(numList []int) {
for needToSortNums := len(numList); needToSortNums > 0; needToSortNums-- {
maxIdx := 0
for idx := 0; idx <= needToSortNums-1; idx++ {
if numList[idx] > numList[maxIdx] {
maxIdx = idx
}
}
// maxIdx位置的元素交换到此次内部循环的最后一个元素的位置上
if numList[maxIdx] > numList[needToSortNums-1] {
temp := numList[needToSortNums-1]
numList[needToSortNums-1] = numList[maxIdx]
numList[maxIdx] = temp
}
}
}
func main() {
numList := []int{10, 1, 5, 3}
fmt.Println(numList)
// [10 1 5 3]
selectSort(numList)
fmt.Println(numList)
// [1 3 5 10]
}