本文介绍: 这样可以减少不必要的交换操作提高排序效率。同时,由于每一趟遍历中的交换操作次数减少,也减少了数据移动次数,进一步提高了排序效率选择排序的基本思想通过不断选择剩余元素中的最小(或最大元素,将其放置到已排序序列末尾,从而逐步构建有序序列选择排序是一种简单的排序算法,它每次从待排序的元素选择最小(或最大)的元素,将其放到已排序序列的末尾,直到整个序列排序完成。:如果a原本在b前面,而a=b,排序之后 a 可能出现b 的后面。:如果a原本在b前面,而a=b,排序之后a仍然在b的前面

算法原理

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

算法描述

选择排序是一种简单的排序算法,它每次从待排序的元素中选择最小(或最大)的元素,将其放到已排序序列的末尾,直到整个序列排序完成
选择排序的基本思想通过不断选择剩余元素中的最小(或最大)元素,将其放置到已排序序列的末尾,从而逐步构建有序序列。具体步骤如下

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

动画演示

在这里插入图片描述

代码实现

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. 设置一个标志位,记录每一趟遍历最小(或最大)元素的位置,避免不必要的交换操作
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. 使用双指针,分别指向已排序序列的末尾和待排序序列的开头,减少交换操作次数
public void selectionSort(int[] arr) {
        int n = arr.length;
        int left = 0;
        int right = n - 1;
    
        //直到leftright指针相遇。
        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] &gt; 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的函数

原文地址:https://blog.csdn.net/WriteBug001/article/details/134734623

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_43832.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注