详解十大经典排序算法(二):选择排序(Selection Sort)

算法原理

选择排序通过重复选择数组中最小元素,将其与未排序部分的第一个元素交换,实现排序。

算法描述

选择排序是一种简单的排序算法,它每次从待排序的元素中选择最小(或最大)的元素,将其放到已排序序列的末尾,直到整个序列排序完成。

选择排序的基本思想是通过不断选择剩余元素中的最小(或最大)元素,将其放置到已排序序列的末尾,从而逐步构建有序序列。具体步骤如下:

  1. 遍历待排序序列,找到最小(或最大)的元素。
  2. 将最小(或最大)元素与待排序序列的第一个元素交换位置,将该元素放置到已排序序列的末尾。
  3. 缩小待排序序列的范围,将已排序序列的长度增加1。
  4. 重复步骤1-3,直到待排序序列为空。

动画演示

代码实现

java 复制代码
public void selectSort(int arr[]) {
        int n = arr.length;
        for (int i = 0; i < n - 1; i++) {
            int minIndex = i;
            for (int j = i + 1; j < n; j++) {
                if (arr[j] < arr[minIndex]) {
                    minIndex = j;
                }
            }
            //交换 arr[i]和arr[minIndex]
            int temp = arr[i];
            arr[i] = arr[minIndex];
            arr[minIndex] = temp;
        }
    }

算法复杂度

时间复杂度(最坏) 时间复杂度(最好) 时间复杂度(平均) 空间复杂度 稳定性
O(n^2) O(n^2) O(n^2) O(1) 不稳定

选择排序的优化方式:

  1. 设置一个标志位,记录每一趟遍历中最小(或最大)元素的位置,避免不必要的交换操作。
java 复制代码
public void selectionSort(int[] arr) {
        int n = arr.length;
        for (int i = 0; i < n - 1; i++) {
            int minIndex = i;
            for (int j = i + 1; j < n; j++) {
                if (arr[j] < arr[minIndex]) {
                    minIndex = j;
                }
            }
            if (minIndex != i) {
                int temp = arr[i];
                arr[i] = arr[minIndex];
                arr[minIndex] = temp;
            }
        }
    }
  1. 使用双指针,分别指向已排序序列的末尾和待排序序列的开头,减少交换操作的次数。
java 复制代码
public void selectionSort(int[] arr) {
        int n = arr.length;
        int left = 0;
        int right = n - 1;
    
        //直到left和right指针相遇。
        while (left < right) {
            int minIndex = left;
            int maxIndex = left;
            //寻找最小和最大元素下标
            for (int i = left + 1; i <= right; i++) {
                if (arr[i] < arr[minIndex]) {
                    minIndex = i;
                }
                if (arr[i] > arr[maxIndex]) {
                    maxIndex = i;
                }
            }
            //如果最小元素的位置不等于left,则将最小元素与已排序序列的末尾元素交换位置。
            //此处的末尾是数值越来越大:1 3 4 ...
            if (minIndex != left) {
                int temp = arr[left];
                arr[left] = arr[minIndex];
                arr[minIndex] = temp;
            }
            //如果最大元素的位置等于left,则将最大元素的位置更新为最小元素的位置。
            //因为上一步已经把最大元素换到了最小元素位置,所以需要重新设置下标
            if (maxIndex == left) {
                maxIndex = minIndex;
            }
            //如果最大元素的位置不等于right,则将最大元素与待排序序列的开头元素交换位置。
            //此处的开头是数值越来越小:... 5 6 9
            if (maxIndex != right) {
                int temp = arr[right];
                arr[right] = arr[maxIndex];
                arr[maxIndex] = temp;
            }
            left++;
            right--;
        }
    }

通过使用双指针的优化方式,可以减少交换操作的次数。在每一趟遍历中,同时找到最小元素和最大元素的位置,并根据情况进行交换操作。这样可以减少不必要的交换操作,提高排序的效率。同时,由于每一趟遍历中的交换操作次数减少,也减少了数据的移动次数,进一步提高了排序的效率。


相关概念

稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。

不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。

时间复杂度:对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。

空间复杂度:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模n的函数。

相关推荐
轻抚酸~2 小时前
KNN(K近邻算法)-python实现
python·算法·近邻算法
Yue丶越4 小时前
【C语言】字符函数和字符串函数
c语言·开发语言·算法
小白程序员成长日记4 小时前
2025.11.24 力扣每日一题
算法·leetcode·职场和发展
有一个好名字4 小时前
LeetCode跳跃游戏:思路与题解全解析
算法·leetcode·游戏
AndrewHZ5 小时前
【图像处理基石】如何在图像中提取出基本形状,比如圆形,椭圆,方形等等?
图像处理·python·算法·计算机视觉·cv·形状提取
蓝牙先生5 小时前
简易TCP C/S通信
c语言·tcp/ip·算法
松涛和鸣6 小时前
从零开始理解 C 语言函数指针与回调机制
linux·c语言·开发语言·嵌入式硬件·排序算法
xiaoye-duck7 小时前
计数排序:高效非比较排序解析
数据结构
稚辉君.MCA_P8_Java9 小时前
Gemini永久会员 Java中的四边形不等式优化
java·后端·算法
稚辉君.MCA_P8_Java9 小时前
通义 插入排序(Insertion Sort)
数据结构·后端·算法·架构·排序算法