算法: 选择排序

选择排序(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]

微信搜索:小码侠

《算法: 选择排序》 长按二维码关注我们

    原文作者:小码侠
    原文地址: https://www.jianshu.com/p/cd37eb2e4530
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞