当前位置: 首页 > news >正文

【Python 算法零基础 4.排序 ① 选择排序】

就算经历各番碰撞,幸运也将一直站在我这边 

                                                                —— 25.5.18

一、引言

        选择排序(Selection Sort) 是一种简单直观的排序算法。它首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕


二、算法思想 

        第一步:在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。

        第二步:再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。

        重复第二步,直到所有元素均排序完毕


三、算法分析

1.时间复杂度

T(n) = O(n ^ 2)

2.空间复杂度

S(n) = O(1)


四、选择排序的优缺点

1.选择排序的优点

① 简单易懂

选择排序是一种简单直观的排序算法,容易理解和实现。

② 原地排序

选择排序不需要额外的存储空间,只使用原始数组进行排序

③ 适用于小型数组

对于小型数组,选择排序的性能表现较好。


2.选择排序的缺点

① 时间复杂度高

在处理大规模数据时效率较低

② 不稳定

选择排序在排序过程中可能会改变相同元素的相对顺序,因此它是一种不稳定的算法


3.优化方案

【选择排序】在众多排序算法中效率较低,时间复杂度为 O(n^2)

当有 n = 100000 个数字。即使我们的计算机速度超快,并且可以在1秒内计算 10^8 次操作,但选择排序仍需要大约一百秒才能完成。

每一个内层循环是从一个区间中找到一个最小值,并且更新这个最小值。是一个【动态区间最值 】问题,所以这一步,我们是可以通过【线段树】来优化的。这样就能将内层循环的时间复杂度优化成 O(log2n) 了,总的时间复杂度就变成了 O(nlog2n)。常见的选择排序优化是采用堆排序来进行优化


五、实战练习

选择排序的代码实现

选择排序的核心思想是每轮选择剩余元素中的最小(大)值,并将其放到已排序部分的末尾。

选择排序后的列表(数组)应遵守小(大)的在前,大(小)的在后的升(降)序顺序

def selectionSort(arr:List) —> arr:Listn = len(arr)for i in range(n):min = ifor j in range(i + 1, n):if arr[j] < arr[min]:min = jarr[i], arr[min] = arr[min], arr[i]

75. 颜色分类

给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地 对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

    必须在不使用库内置的 sort 函数的情况下解决这个问题。

    示例 1:

    输入:nums = [2,0,2,1,1,0]
    输出:[0,0,1,1,2,2]
    

    示例 2:

    输入:nums = [2,0,1]
    输出:[0,1,2]
    

    提示:

    • n == nums.length
    • 1 <= n <= 300
    • nums[i] 为 01 或 2

    思路与算法

    ① 遍历数组

    外层循环 i 从 0 到 n-1n 为数组长度),表示当前待排序的位置。

    ② 寻找最小值

    初始化 min = i,假设当前位置 i 的元素最小。内层循环 j 从 i+1 到 n-1,比较 arr[j] 与 arr[min]:若 arr[j] < arr[min],更新 min = j(记录更小值的索引)。

    ③ 交换元素

    内层循环结束后,将 arr[i] 与 arr[min] 交换,确保位置 i 为当前最小值。

    ④ 重复

    外层循环继续,逐步将剩余元素中的最小值放到正确位置。

    class Solution:def selectionSort(self, arr: List[int]):n = len(arr)for i in range(n):min = ifor j in range(i + 1, n):if arr[j] < arr[min]:min = j arr[i], arr[min] = arr[min], arr[i] def sortColors(self, nums: List[int]) -> None:"""Do not return anything, modify nums in-place instead."""self.selectionSort(nums)


    4. 寻找两个正序数组的中位数

    给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。

    示例 1:

    输入:nums1 = [1,3], nums2 = [2]
    输出:2.00000
    解释:合并数组 = [1,2,3] ,中位数 2
    

    示例 2:

    输入:nums1 = [1,2], nums2 = [3,4]
    输出:2.50000
    解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
    

    提示:

    • nums1.length == m
    • nums2.length == n
    • 0 <= m <= 1000
    • 0 <= n <= 1000
    • 1 <= m + n <= 2000
    • -106 <= nums1[i], nums2[i] <= 106

    思路与算法 

    ① 合并数组

    将 nums2 中的所有元素逐个添加到 nums1 的末尾。此时 nums1 包含两个数组的所有元素,但无序

    ② 排序合并后的数组

    使用选择排序对 nums1 进行排序,选择排序的时间复杂度为 O ((m+n)²),其中 m 和 n 分别是两个数组的长度。

    ③ 计算中位数

    设合并后数组的长度为 total_length

    奇数长度:直接返回中间元素 nums1[total_length // 2]

    偶数长度:返回中间两个元素的平均值 (nums1[total_length//2 - 1] + nums1[total_length//2]) / 2.0

    class Solution:def selectionSort(self, arr: List[int]):n = len(arr)for i in range(n):min = ifor j in range(i + 1, n):if arr[j] < arr[min]:min = j arr[i], arr[min] = arr[min], arr[i] def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:for x in nums2:nums1.append(x)n = len(nums1)self.selectionSort(nums1)if n % 2 == 1:return nums1[n // 2]return (nums1[n // 2 - 1] + nums1[n // 2]) / 2.0


    747. 至少是其他数字两倍的最大数

    给你一个整数数组 nums ,其中总是存在 唯一的 一个最大整数 。

    请你找出数组中的最大元素并检查它是否 至少是数组中每个其他数字的两倍 。如果是,则返回 最大元素的下标 ,否则返回 -1 。

    示例 1:

    输入:nums = [3,6,1,0]
    输出:1
    解释:6 是最大的整数,对于数组中的其他整数,6 至少是数组中其他元素的两倍。6 的下标是 1 ,所以返回 1 。
    

    示例 2:

    输入:nums = [1,2,3,4]
    输出:-1
    解释:4 没有超过 3 的两倍大,所以返回 -1 。
    

    提示:

    • 2 <= nums.length <= 50
    • 0 <= nums[i] <= 100
    • nums 中的最大元素是唯一的

    思路与算法

    ① 寻找最大值索引

    遍历数组 nums,记录最大值的索引 max

    ② 排序数组

    使用选择排序对 nums 进行升序排列。

    ③ 比较最大元素与次大元素

    排序后,最大元素位于 nums[-1],次大元素位于 nums[-2]

    ④ 检查最大元素是否至少是次大元素的两倍

    若是,返回之前记录的最大值索引 max。否则,返回 -1

    class Solution:def selectionSort(self, arr: List[int]):n = len(arr)for i in range(n):min = ifor j in range(i + 1, n):if arr[j] < arr[min]:min = j arr[i], arr[min] = arr[min], arr[i] def dominantIndex(self, nums: List[int]) -> int:max = 0n = len(nums)for i in range(n):if nums[i] > nums[max]:max = iself.selectionSort(nums)maxCount = nums[-1]subMaxCount = nums[-2]if maxCount >= 2 * subMaxCount:return maxreturn -1

    相关文章:

  • 为何选择Python:全面解析其优势与发展前景
  • Linux下载国外软件镜像的加速方法(以下载Python-3.8.0.tgz为例)
  • Java可变参数与Collections工具类详解
  • 系统架构设计师考前冲刺笔记-第1章-系统工程与信息系统基础
  • 深入解析Java事件监听机制与应用
  • GOP模式调节画面质量讲解
  • 【ROS2】 核心概念6——通信接口语法(Interfaces)
  • 【QGIS二次开发】地图编辑-07
  • LWIP的NETCONN接口
  • 生产级编排AI工作流套件:Flyte全面使用指南 — Data input/output
  • 【常用算法:查找篇】9.AVL树深度解析:动态平衡二叉树的原理、实现与应用
  • USB传输速率 和 RS-232/RS-485串口协议速率 的倍数关系
  • 备忘录模式
  • 类的加载过程详解
  • LINQ:统一查询语法的强大工具
  • 服务端HttpServletRequest、HttpServletResponse、HttpSession
  • 前端动画库 Anime.js 的V4 版本,兼容 Vue、React
  • 初始C++:类和对象(中)
  • 游戏引擎学习第293天:移动Familiars
  • 线程池核心线程永续机制:从源码到实战的深度解析
  • 2025全球城市科技传播能力指数出炉,上海位列第六
  • 陈刚:推动良好政治生态和美好自然生态共生共优相得益彰
  • 光速晋级!2025年多哈世乒赛孙颖莎4比0战胜对手
  • 高飞已任南航集团党组副书记
  • 江西4人拟任县(市、区)委书记,其中一人为“80后”
  • “GoFun出行”订单时隔7年扣费后续:平台将退费,双方已和解