[特殊字符]算法详解——简单选择排序:像挑水果一样排序,一文搞懂核心原理!

🔥简单选择排序:像挑水果一样排序,一文搞懂核心原理!

🔥为了更好的让大家理解算法这里推荐一个算法可视化的网站https://staying.fun/zh/features/algorithm-visualize

复制文章中JavaScript代码示例到这个网站上就可以看到可视化算法运算的过程了!大家快点来试试吧!!!!

一、算法原理:从 “挑最小” 到 “排顺序” 的智慧

在这里插入图片描述

简单选择排序是一种直观的排序算法,其核心思想是 ** 每一趟从待排序的数据元素中选出最小(或最大)的一个元素,** 并将其放到已排序序列的末尾。整个过程类似于在一堆水果中依次挑选出最小的苹果,放到篮子的前端。

1.1 算法步骤

初始状态:假设第一个元素是当前最小值。

遍历比较:从第二个元素开始,逐个比较,找到实际最小值。

交换位置:将找到的最小值与当前位置元素交换。

重复操作:对剩余未排序元素重复上述步骤,直到所有元素有序。💡 类比场景:整理书架时,每次从剩余书籍中挑出最薄的一本,放到已整理区域的末尾。

二、JavaScript 代码实现与注释

理解了算法原理,我们来看 JavaScript 代码如何实现简单选择排序。代码中有详细注释,方便大家理解每一步操作。

// 简单选择排序函数

function selectionSort(arr) {

   // 获取数组长度

   const len = arr.length;

   // 外层循环:控制已排序序列的末尾位置

   for (let i = 0; i < len - 1; i++) {

       // 假设当前索引i处的元素是最小值

       let minIndex = i;

       // 内层循环:从i+1位置开始寻找最小值

       for (let j = i + 1; j < len; j++) {

           // 如果找到比当前最小值还小的元素,更新最小值索引

           if (arr[j] < arr[minIndex]) {

               minIndex = j;

           }

       }

       // 如果找到的最小值不是当前假设的最小值(即i位置的元素),交换它们

       if (minIndex!== i) {

           // 利用临时变量temp交换arr[i]和arr[minIndex]

           let temp = arr[i];

           arr[i] = arr[minIndex];

           arr[minIndex] = temp;

       }

   }

   // 返回排序后的数组

   return arr;

}

// 测试示例

let testArray = [64, 25, 12, 22, 11];

// 调用选择排序函数并打印结果

console.log(selectionSort(testArray));

在上述代码中,selectionSort函数实现了简单选择排序。外层循环遍历数组,每次确定一个最小值并将其放到已排序序列的末尾。内层循环从当前位置的下一个元素开始,寻找剩余未排序元素中的最小值。如果找到的最小值不是当前位置的元素,就通过临时变量temp交换它们。最后,返回排序后的数组,并通过console.log打印测试数组的排序结果。

三、算法关键点解析

3.1 双重循环结构

简单选择排序的代码中使用了双重循环结构,这是实现排序的关键部分。外层循环控制排序轮次,由于每一轮确定一个元素的最终位置,对于长度为n的数组,只需进行n - 1轮排序,就能使整个数组有序。例如,数组[64, 25, 12, 22, 11],长度为 5,外层循环只需执行 4 次。

内层循环则负责在每一轮中遍历剩余未排序的元素,找出其中的最小值索引。以内层循环for (let j = i + 1; j < len; j++)为例,它从外层循环当前索引i的下一个位置开始,一直遍历到数组末尾,通过比较arr[j]arr[minIndex],不断更新最小值的索引minIndex 。这样,每一轮内层循环结束后,minIndex就指向了当前未排序部分的最小值。 双重循环结构相互配合,外层循环逐步扩大已排序序列,内层循环为每一轮找到合适的元素添加到已排序序列末尾,从而实现整个数组的排序。

3.2 交换操作

在简单选择排序中,交换操作是将找到的最小值与当前位置元素进行互换。每一轮外层循环中,只有当找到的最小值索引minIndex不等于当前位置索引i时,才会执行交换操作。例如在if (minIndex!== i)条件判断为真时,通过临时变量temp进行交换:let temp = arr[i]; arr[i] = arr[minIndex]; arr[minIndex] = temp;。这种交换方式的优点是每轮仅交换一次,相比于其他一些排序算法(如冒泡排序可能在每一轮有多次交换),减少了数据移动次数,在一定程度上提高了效率。不过,即使数组已经是有序的,简单选择排序仍需进行n - 1次比较(因为它不知道数组已有序,依然按照既定步骤寻找最小值),只是不会有交换操作。这也是该算法在面对有序数组时的一个不足,没有充分利用数组已有的顺序信息。

3.3 稳定性问题

简单选择排序是一种不稳定的排序算法 。稳定性是指在排序过程中,相同元素的相对顺序是否保持不变。简单选择排序中,相同元素可能因交换改变相对顺序。例如,对于数组[5, 5, 1],第一轮排序时,会将最小值 1 与第一个 5 交换位置,得到[1, 5, 5],原本两个 5 的相对顺序发生了变化。在一些应用场景中,如果对元素的相对顺序有严格要求(比如对学生成绩排序,成绩相同的学生要保持原来的录入顺序),简单选择排序就不太适用,需要选择稳定的排序算法,如归并排序、冒泡排序等。

四、算法复杂度分析

4.1 时间复杂度

简单选择排序的时间复杂度为 O ( n 2 ) O(n^2) O(n2),其中 n n n是待排序数组的长度。无论数组初始状态如何(最好、最坏或平均情况),时间复杂度均为 O ( n

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PGFA

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值