データ構造とアルゴリズム(Golang実装)(20)ソートアルゴリズム選択ソート

並べ替えを選択

選択ソートは、一般に、単純選択ソート(直接選択ソートとも呼ばれます)を指します。バブルソートのように要素を隣接して交換するのではなく、最小の要素を選択し、反復ごとに1回だけ交換する必要があります。交換の数はバブリングよりはるかに少ないですが、効率はバブリングソートと同じくらい悪いです。

選択ソートは、選択ソートアルゴリズムです。

ポーカーをプレイするときは、常に左から右にスキャンしてから、一番左のカードを左端に置き、次に2番目に小さいカードを2番目のカードから左から右にスキャンして、一番小さいカードに置きます。カードの右側で、これを繰り返します。選択の並べ替えは、ポーカーをプレイするときの並べ替えに特に似ています。

1.アルゴリズムの紹介

乱数列の束のような、があります5 9 1 6 8 14 6 49 25 4 6 3

最初の反復は、最初の数値から開始して、左から右にスキャンし、最小の数値1を見つけて、シーケンス内の最初の数値と位置を入れ替えます。

2番目の反復は、2番目の数値から開始して、左から右にスキャンし、2番目に小さい数値3を見つけて、シーケンス内の2番目の数値と位置を交換します。

3回目の反復では、3番目の数値から開始して左から右にスキャンし、3番目に小さい数値4を見つけて、シーケンス内の3番目の数値と位置を交換します。

N番目の反復:...

交換後の最終結果は次のとおり1 3 4 5 6 6 6 8 9 14 25 49です。並べ替えられていることがわかります。

シーケンスをスキャンして最小数を見つけ、最初の数と交換し、最初の数を除外するたびに、この操作を2番目の数から繰り返します。この並べ替えは、単純選択並べ替えと呼ばれます。

簡単な例として、4要素シーケンスのソートを選択します4 2 9 1

[]表示排好序

起始: 4 2 9 1  未排序数列从左扫描最小的数是 1,与第一个元素 4 交换,交换 1,4
一轮: [1] 2 9 4 未排序数列从左扫描最小的数是 2,不需要交换
二轮: [1 2] 9 4 未排序数列从左扫描最小的数是 4,与第三个元素 9 交换,交换 4,9
三轮: [1 2 4] 9 未排序数列只有 1 个数,结束
结果: [1 2 4 9]

スキャンプロセスも比較プロセスであるため、バブリングソートと同じくらい多くの比較がありますが、交換回数は1ラウンドあたり1に減ります。ベストと最悪時間計算量が残っています:O(n^2)

選択の並べ替えは、配列などの不安定な並べ替えアルゴリズムです。[5 6 5 1]最初の反復で最小数は1であり、最初の要素と5位置交換します。その結果、数1と数が5位置を交換し、5並べ替え後に2つの同じ数になります。場所が変更されました。

2.アルゴリズムの実装

package main

import "fmt"

func SelectSort(list []int) {
    n := len(list)
    // 进行 N-1 轮迭代
    for i := 0; i < n-1; i++ {
        // 每次从第 i 位开始,找到最小的元素
        min := list[i] // 最小数
        minIndex := i  // 最小数的下标
        for j := i + 1; j < n; j++ {
            if list[j] < min {
                // 如果找到的数比上次的还小,那么最小的数变为它
                min = list[j]
                minIndex = j
            }
        }

        // 这一轮找到的最小数的下标不等于最开始的下标,交换元素
        if i != minIndex {
            list[i], list[minIndex] = list[minIndex], list[i]
        }
    }
}

func main() {
    list := []int{5, 9, 1, 6, 8, 14, 6, 49, 25, 4, 6, 3}
    SelectSort(list)
    fmt.Println(list)
}

反復ごとに、このラウンドmin最小数:最小数の添え字:を維持しminIndex、スキャンを開始します。スキャン数がこの数より少ない場合は、最小と最小の添え字を置き換えます。交換は、その後交換すべきかどうかを決定しますlist[i], list[minIndex] = list[minIndex], list[i]

3、アルゴリズムの改善

上記のアルゴリズムは、特定の数から開始して最後までスキャンする必要があります。アルゴリズムを最適化して、複雑さを半分に減らすことができます。

各ラウンドで、最小数を見つけることに加えて、最大数も見つけて、前部要素と後部要素と別々に交換するので、次のようにサイクル数が半分になります。

package main

import "fmt"

func SelectGoodSort(list []int) {
    n := len(list)

    // 只需循环一半
    for i := 0; i < n/2; i++ {
        minIndex := i // 最小值下标
        maxIndex := i // 最大值下标

        // 在这一轮迭代中要找到最大值和最小值的下标
        for j := i + 1; j < n-i; j++ {
            // 找到最大值下标
            if list[j] > list[maxIndex] {
                maxIndex = j // 这一轮这个是大的,直接 continue
                continue
            }
            // 找到最小值下标
            if list[j] < list[minIndex] {
                minIndex = j
            }
        }

        if maxIndex == i && minIndex != n-i-1 {
            // 如果最大值是开头的元素,而最小值不是最尾的元素
            // 先将最大值和最尾的元素交换
            list[n-i-1], list[maxIndex] = list[maxIndex], list[n-i-1]
            // 然后最小的元素放在最开头
            list[i], list[minIndex] = list[minIndex], list[i]
        } else if maxIndex == i && minIndex == n-i-1 {
            // 如果最大值在开头,最小值在结尾,直接交换
            list[minIndex], list[maxIndex] = list[maxIndex], list[minIndex]
        } else {
            // 否则先将最小值放在开头,再将最大值放在结尾
            list[i], list[minIndex] = list[minIndex], list[i]
            list[n-i-1], list[maxIndex] = list[maxIndex], list[n-i-1]
        }
    }
}

func main() {
    list := []int{5}
    SelectGoodSort(list)
    fmt.Println(list)

    list1 := []int{5, 9}
    SelectGoodSort(list1)
    fmt.Println(list1)

    list2 := []int{5, 9, 1}
    SelectGoodSort(list2)
    fmt.Println(list2)

    list3 := []int{5, 9, 1, 6, 8, 14, 6, 49, 25, 4, 6, 3}
    SelectGoodSort(list3)
    fmt.Println(list3)

    list4 := []int{5, 9, 1, 6, 8, 14, 6, 49, 25, 4, 6}
    SelectGoodSort(list4)
    fmt.Println(list4)
}

出力:

[5]
[5 9]
[1 5 9]
[1 3 4 5 6 6 6 8 9 14 25 49]
[1 4 5 6 6 6 8 9 14 25 49]

最適化されたソートはまだ非常に遅く、理解しやすいですが、エンジニアリングにはお勧めできません。

シリーズ記事エントリー

私は、スター陳思い、私が個人的に書かれているようこそ(Golangが達成)のデータ構造とアルゴリズムの記事で始まる、より親しみやすいGitBookを読むために

おすすめ

転載: www.cnblogs.com/nima/p/12724853.html