选择排序(Selection sort)是一种简单直观的排序算法,复杂度O(N^2)。重复挑选 最小/最大
的元素 ,放在起始位置。直到全部元素排序完成。
如需要对以下数据排序:
{5, 2, 4, 3, 1}
程序运行过程如下
第 1 次找到最小元素位置:4
,值为 1
,排序结果如下:
[5 2 4 3 1
] => [1
2 4 3 5]
第 2 次找到最小元素位置:1
,值为 2
,排序结果如下:
[1 2
4 3 5] => [1 2
4 3 5]
第 3 次找到最小元素位置:3
,值为 3
,排序结果如下:
[1 2 4 3
5] => [1 2 3
4 5]
第 4 次找到最小元素位置:3
,值为 4
,排序结果如下:
[1 2 3 4
5] => [1 2 3 4
5]
第 5 次找到最小元素位置:4
,值为 5
,排序结果如下:
[1 2 3 4 5
] => [1 2 3 4 5
]
最终结果如下:
[1 2 3 4 5]
代码实现
Go
package main
import (
"fmt"
)
func main() {
//声明数组
numbers := []int{5, 2, 4, 3, 1}
//获取数组长度
length := len(numbers)
//遍历数组
for i := 0; i < length ; i++ {
//最小元素下标
minIndex := i
for j := i+1; j < length ; j++ {
//重复挑选 `最小/最大`的元素 ,放在起始位置
if numbers[j] < numbers[minIndex] {
//如果满足交换条件,设置最小位置
minIndex = j
}
}
swap := fmt.Sprintf("%v",numbers)
//判断是否需要交换数据
if i != minIndex {
numbers[i], numbers[minIndex] = numbers[minIndex], numbers[i]
}
fmt.Printf("\n第 %d 次找到最小元素位置:`%d` ,值为 `%d` ,排序结果如下:\n\n",i+1 ,minIndex , numbers[i]);
fmt.Printf("%s => %v \n",swap,numbers)
}
fmt.Println("\n最终结果如下:\n")
//排序完成
fmt.Println(numbers)
}
Python
# -*- coding: UTF-8 -*-
## 定义数组
numbers = [5, 2, 4, 3, 1]
# 取得长度
length = len(numbers)
for i in range(0, length-1):
# 记录最小位置
minIndex = i
for j in range(i+1,length):
#重复挑选 `最小/最大`的元素 ,放在起始位置
if numbers[j] < numbers[minIndex]:
minIndex = j
if i != minIndex:
#判断是否需要交换数据
numbers[i], numbers[minIndex] = numbers[minIndex], numbers[i]
print(numbers)
优化
选择排序的核心是重复挑选最大/最小
的元素放在起始位置,如果我们每次都挑选最小
的放在起始位置,那么最大
的数据就应该放在结束位置,既然需要重复挑选,如果我们可以每次把最小
,最大
都挑选出来,如此就可以大大的节省时间。
优化效果
[5 2 4 3 1]
第 1 次找到最小元素位置:4
,值为 1
;找到最大元素位置:0
,值为 5
。,排序结果如下:
[5
2 4 3 1
] => [1 2 4 3 5]
第 2 次找到最小元素位置:1
,值为 2
;找到最大元素位置:2
,值为 4
。,排序结果如下:
[1 2
4
3 5] => [1 2 3 4 5]
最终结果如下:
[1 2 3 4 5]
代码实现
GO
package main
import (
"fmt"
)
func main() {
//声明获取一个随机数组
//[]int{5, 2, 4, 3, 1}
numbers := []int{5, 2, 4, 3, 1} // utils.GetRandSlices(10, 5)
fmt.Println(numbers)
//获取数组长度
length := len(numbers)
//遍历数组
endIndex := length - 1 //结束数据位置
for i := 0; i < length; i++ {
//排序结束
if i >= endIndex {
break
}
//最小元素下标
minIndex := i
maxIndex := i
for j := i + 1; j < endIndex+1; j++ {
//重复挑选 `最小/最大`的元素 ,放在起始位置
if numbers[j] < numbers[minIndex] {
//如果满足交换条件,设置最小位置
minIndex = j
}
//优化:
//重复挑选 `最小/最大`的元素 ,放在结束位置
if numbers[j] > numbers[maxIndex] {
//如果满足交换条件,设置最小位置
maxIndex = j
}
}
swap := fmt.Sprintf("%v", numbers)
fmt.Printf("\n第 %d 次找到最小元素位置:`%d` ,值为 `%d` ;找到最大元素位置:`%d` ,值为 `%d`。,排序结果如下:\n\n", i+1, minIndex, numbers[minIndex], maxIndex, numbers[maxIndex]);
//判断是否需要交换数据
if i != minIndex {
numbers[i], numbers[minIndex] = numbers[minIndex], numbers[i]
}
if i == maxIndex {
maxIndex = minIndex
}
if endIndex != maxIndex {
numbers[endIndex], numbers[maxIndex] = numbers[maxIndex], numbers[endIndex]
}
endIndex -- //每操作完成一次,结束位置就需要挪动一次
fmt.Printf("%s => %v \n", swap, numbers)
}
fmt.Println("\n最终结果如下:\n")
//排序完成
fmt.Println(numbers)
}
# -*- coding: UTF-8 -*-
## 定义数组
numbers = [5, 2, 4, 3, 1]
# 取得长度
length = len(numbers)
end = length - 1
for i in range(0, length - 1):
if i > end:
break
# 记录最小位置
minIndex = i
maxIndex = i
for j in range(i + 1, end + 1):
# 重复挑选 `最小/最大`的元素 ,放在起始位置
if numbers[j] < numbers[minIndex]:
minIndex = j
# 优化,挑选最大数据
if numbers[j] > numbers[maxIndex]:
maxIndex = j
if i != minIndex:
# 判断是否需要交换数据
numbers[i], numbers[minIndex] = numbers[minIndex], numbers[i]
# 数据被转移的意外情况。
if i == maxIndex:
maxIndex = minIndex
if end != maxIndex:
# 判断是否需要交换数据
numbers[end], numbers[maxIndex] = numbers[maxIndex], numbers[end]
end -= 1
print(numbers)
# [1, 2, 3, 4, 5]
微信搜索:小码侠

网友评论