Menu
×
   ❮   
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP HOW TO W3.CSS C C++ C# BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS R TYPESCRIPT ANGULAR GIT POSTGRESQL MONGODB ASP AI GO KOTLIN SASS VUE DSA GEN AI SCIPY AWS CYBERSECURITY DATA SCIENCE
     ❯   

DSA 选择排序


选择排序

选择排序算法在数组中找到最小值并将其移动到数组的开头。

速度

{{ msgDone }}

该算法会一遍又一遍地遍历数组,将下一个最小值移动到数组未排序部分的开头,直到数组排序完成。

工作原理

  1. 遍历数组以找到最小值。
  2. 将最小值移动到数组未排序部分的开头。
  3. 根据数组中的值数量,再次遍历数组。

继续阅读以充分理解选择排序算法及其实现方法。


手动运行

在用编程语言实现选择排序算法之前,让我们手动运行一次简短的数组,以了解其工作原理。

步骤 1:我们从一个未排序的数组开始。

[ 7, 12, 9, 11, 3]

步骤 2:遍历数组,一次一个值。哪个值最小?3,对吧?

[ 7, 12, 9, 11, 3]

步骤 3:将最小值 3 移动到数组的开头。

[ 3, 7, 12, 9, 11]

步骤 4:从 7 开始,查看数组中剩下的值。7 是最小值,并且已经位于数组的开头,因此不需要移动它。

[ 3, 7, 12, 9, 11]

步骤 5:查看数组中剩下的值:12、9 和 11。9 是最小值。

[ 3, 7, 12, 9, 11]

步骤 6:将 9 移动到开头。

[ 3, 7, 9, 12, 11]

步骤 7:查看 12 和 11,11 是最小值。

[ 3, 7, 9, 12, 11]

步骤 8:将其移动到开头。

[ 3, 7, 9, 11, 12]

最后,数组已排序。


运行下面的模拟以查看上述步骤的动画演示

{{ msgDone }}
[
{{ x.dieNmbr }}
]

手动运行:发生了什么?

为了完全理解该算法,以便我们用编程语言实现它,我们必须理解上述步骤。

你能看到最小值 3 发生了什么吗?在步骤 3 中,它被移动到了数组的开头,它应该在的位置,但在此步骤中,数组的其余部分仍然未排序。

因此,选择排序算法必须一遍又一遍地遍历数组,每次将下一个最小值移动到数组未排序部分的开头,使其处于正确的位置。排序持续进行,直到最大值 12 停留在数组的末尾。这意味着我们需要遍历数组 4 次,以排序 5 个值的数组。

每次算法遍历数组时,数组中剩下的未排序部分都会变短。

现在,我们将利用学到的知识,用编程语言实现选择排序算法。


选择排序实现

要使用编程语言实现选择排序算法,我们需要

  1. 一个包含要排序的值的数组。
  2. 一个内循环,它遍历数组,找到最小值,并将该值移动到数组的开头。每次运行时,此循环必须遍历少一个值。
  3. 一个外循环,它控制内循环运行的次数。对于具有 \(n\) 个值的数组,此外循环必须运行 \(n-1\) 次。

生成的代码如下所示

示例

my_array = [64, 34, 25, 5, 22, 11, 90, 12]

n = len(my_array)
for i in range(n-1):
    min_index = i
    for j in range(i+1, n):
        if my_array[j] < my_array[min_index]:
            min_index = j
    min_value = my_array.pop(min_index)
    my_array.insert(i, min_value)

print("Sorted array:", my_array)
运行示例 »

选择排序移位问题

选择排序算法可以稍微改进一下。

在上面的代码中,最小值元素被移除,然后插入到数组的开头。

每次移除下一个最小值数组元素时,所有后续元素必须向下移动一位以弥补移除。

Shifting other elements when an array element is removed.

这些移位操作需要大量时间,而且我们还没有完成!在找到并移除最小值 (5) 后,它被插入到数组的开头,导致所有后续值向上移动一位,为新值腾出空间,如下面的图像所示。

Shifting other elements when an array element is inserted.

注意:如果您使用的是高级编程语言,例如 Python 或 Java,您将不会看到这些移位操作在代码中发生,但移位操作仍然在后台发生。这些移位操作需要计算机额外的时间,这可能是一个问题。


解决方案:交换值!

与其进行所有移位操作,不如将最小值 (5) 与第一个值 (64) 交换,如下所示。

Shifting other elements when an array element is inserted.

我们可以像上面的图像所示那样交换值,因为最小值最终会处于正确的位置,并且我们将另一个交换的值放在哪里并不重要,因为它还没有排序。

这里有一个模拟,展示了这种改进后的使用交换的选择排序是如何工作的

速度

{{ msgDone }}

以下是用交换实现改进后的选择排序的代码

示例

my_array = [64, 34, 25, 12, 22, 11, 90, 5]

n = len(my_array)
for i in range(n):
    min_index = i
    for j in range(i+1, n):
        if my_array[j] < my_array[min_index]:
            min_index = j   
    my_array[i], my_array[min_index] = my_array[min_index], my_array[i]

print("Sorted array:", my_array)
运行示例 »

选择排序时间复杂度

有关时间复杂度的概括性解释,请访问 此页面

有关选择排序时间复杂度的更全面和详细的解释,请访问 此页面

选择排序对一个具有 \(n\) 个值的数组进行排序。

平均而言,大约 \(\frac{n}{2}\) 个元素被比较,以在每次循环中找到最小值。

选择排序必须大约运行 \(n\) 次循环来找到最小值。

我们得到的时间复杂度为

\[ O( \frac{n}{2} \cdot n) = \underline{\underline{O(n^2)}} \]

选择排序算法的时间复杂度可以用下面的图表来表示

Selection Sort time complexity

如您所见,运行时间与冒泡排序相同:当数组的大小增加时,运行时间会迅速增加。

运行下面的模拟,以查看不同大小数组的运行时间。

红色虚线表示理论时间复杂度 \(O(n^2)\)。

当您运行模拟时,会出现蓝色十字。蓝色十字显示排序一个特定大小的数组需要多少个操作。

{{ this.userX }}

操作次数:{{ operations }}

 

在这个模拟中,我们可以注意到与冒泡排序最显著的差异是,选择排序的最佳情况和最坏情况几乎相同(\(O(n^2)\)),但冒泡排序的最佳情况运行时间只有 \(O(n)\)。

选择排序的最佳情况和最坏情况之间的差异主要在于交换次数。在最佳情况下,选择排序不需要交换任何值,因为数组已经排序。而在最坏情况下,数组已经排序,但顺序错误,因此选择排序必须进行与数组中值数量相同的交换。


DSA 练习

通过练习测试自己

练习

对该数组使用选择排序

[7,12,9,11,3]

以升序排列值,从左到右。

第一次遍历后,最后一个元素的值是多少?



开始练习



×

Contact Sales

If you want to use W3Schools services as an educational institution, team or enterprise, send us an e-mail:
[email protected]

Report Error

If you want to report an error, or if you want to make a suggestion, send us an e-mail:
[email protected]

W3Schools is optimized for learning and training. Examples might be simplified to improve reading and learning. Tutorials, references, and examples are constantly reviewed to avoid errors, but we cannot warrant full correctness of all content. While using W3Schools, you agree to have read and accepted our terms of use, cookie and privacy policy.

Copyright 1999-2024 by Refsnes Data. All Rights Reserved. W3Schools is Powered by W3.CSS.