排序之选择排序|Go主题月

679 阅读2分钟

选择排序为在冒泡排序的基础上进行优化的一种排序算法,每次遍历只进行一次元素交换
为了实现只进行一次交换:

  1. 那么需要在遍历中寻找出待排序元素中的最大值;
  2. 在遍历完后,把最大值放到正确的位置上。

和冒泡排序一样,第一次遍历后,最大元素处于正确的位置上;第二次遍历后,第二大的原始处于正确的位置上;以此类推。 具体排序过程如下图所示(箭头表示交换位置):

  1. 第一轮遍历时,发现最大的数为10,所以把10与最后面的数字交换位置,使得最大的数处于正确的位置上;
  2. 第二轮遍历时,待排序的元素里最大的数为5且已处于正确的位置,无需交换;
  3. 第三轮遍历时,待排序的元素里最大的数为3,需要把3放到正确的位置上。 至此,切片数组已排序完毕。

选择排序.png

时间复杂度: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]
}