2023 跟我一起学算法:选择排序

排序算法

什么是排序?

排序算法用于根据元素上的比较运算符重新排列给定的数组或元素列表。比较运算符用于决定相应数据结构中元素的新顺序。

例如:下面的字符列表按其 ASCII 值的升序排序。也就是说,具有较小 ASCII 值的字符将比具有较高 ASCII 值的字符先放置。

选择排序

选择排序是一种简单而高效的排序算法,其工作原理是重复从列表的未排序部分中选择最小(或最大)元素并将其移动到列表的已排序部分。

"选择排序"算法工作原理

让我们以以下数组为例:arr[] = {64, 25, 12, 22, 11}

第一遍:

  • 对于排序数组中的第一个位置,从索引 0 到 4 顺序遍历整个数组。当前存储64 的第一个位置,遍历整个数组后很明显11是最低值。
  • 因此,将 64 替换为 11。一次迭代后, 11(恰好是数组中的最小值)往往会出现在排序列表的第一个位置。

第二遍:

  • 对于存在 25 的第二个位置,再次按顺序遍历数组的其余部分。
  • 遍历完后,我们发现12是数组中倒数第二小的值,它应该出现在数组的第二位,因此交换这些值。

第三遍:

  • 现在,对于第三个位置,其中存在**25,**再次遍历数组的其余部分并找到数组中存在的第三个最小值。
  • 遍历时,22 是第三个最小值,它应该出现在数组中的第三个位置,因此将22与第三个位置上的元素交换。

第四遍:

  • 类似地,对于第四个位置,遍历数组的其余部分并找到数组中第四小的元素
  • 由于25是第四低的值,因此它将排在第四位。

第五遍:

  • 最后,数组中存在的最大值自动放置在数组的最后一个位置
  • 结果数组是排序后的数组。

代码实现:

javascript

js 复制代码
<script>
// 选择排序的JavaScript程序实现
function swap(arr,xp, yp)
{
	var temp = arr[xp];
	arr[xp] = arr[yp];
	arr[yp] = temp;
}

function selectionSort(arr, n)
{
	var i, j, min_idx;
	// 逐个移动未排序子数组的边界
	for (i = 0; i < n-1; i++)
	{
    // 在未排序的数组中找到最小元素
		min_idx = i;
		for (j = i + 1; j < n; j++)
		if (arr[j] < arr[min_idx])
			min_idx = j;
		// 将找到的最小元素与第一个元素交换位置
		swap(arr,min_idx, i);
	}
}

function printArray( arr, size)
{
	var i;
	for (i = 0; i < size; i++)
		console.log(arr[i] + " ");
}

var arr = [64, 25, 12, 22, 11];
	var n = 5;
	selectionSort(arr, n);
	document.write("Sorted array: <br>");
	printArray(arr, n);
</script>

golang

go 复制代码
package main

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

type ArrT interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64 | ~float32 | ~float64
}

// SelectSort 选择排序
func SelectSort[T ArrT](arr []T) []T {
	var length = len(arr)
	for i := 0; i < length-1; i++ {
		var minIndex = i
		for j := i + 1; j < length; j++ {
			if arr[minIndex] > arr[j] {
				minIndex = j
			}
		}
		arr[minIndex], arr[i] = arr[i], arr[minIndex]
	}

	return arr
}

func Test_SelectSort(t *testing.T) {
	var arr = []int{64, 25, 12, 22, 11}

	var except = []int{11, 12, 22, 25, 64}
	assert.Equal(t, except, SelectSort[int](arr))
}

输出

排序数组: 11 12 22 25 64

选择排序的复杂度分析

时间复杂度:选择排序的时间复杂度为O(N 2 ),因为有两个嵌套循环:

  • 一个循环逐一选择 Array 的元素 = O(N)
  • 另一个循环将该元素与每个其他数组元素进行比较 = O(N)
  • 因此总体复杂度 = O(N) * O(N) = O(N*N) = O(N 2 )

辅助空间: O(1),因为在交换数组中的两个值时,唯一使用的额外内存用于临时变量。选择排序不会进行超过 O(N) 的交换,并且在内存写入成本高昂时非常有用。

选择排序算法的优点

  • 简单易懂。
  • 适用于小型数据集。

选择排序算法的缺点

  • 在最坏和平均情况下,选择排序的时间复杂度为 O(n^2)。
  • 在大型数据集上效果不佳。
  • 不保留具有相同键的项目的相对顺序,这意味着它不稳定。

选择排序的常见问题

Q1. 选择排序算法稳定吗?

选择排序算法的默认实现并不稳定

Q2。选择排序算法是否到位?

是的,选择排序算法是一种原地算法,因为它不需要额外的空间。

相关推荐
kida_yuan28 分钟前
【从零开始】17. 中文摘要提取工具
python·算法·数据分析
未到结局,焉知生死1 小时前
PAT每日三题
算法
进击的炸酱面1 小时前
第三章 线性模型
人工智能·算法·机器学习
立志成为大牛的小牛2 小时前
数据结构——三十一、最小生成树(王道408)
数据结构·学习·程序人生·考研·算法
CoovallyAIHub2 小时前
一致性模型:单步生成高质量图像,破解扩散模型速度瓶颈
深度学习·算法·计算机视觉
JMzz2 小时前
Rust 中的数据结构选择与性能影响:从算法复杂度到硬件特性 [特殊字符]
开发语言·数据结构·后端·算法·性能优化·rust
CodeSheep3 小时前
稚晖君官宣,全球首个0代码机器人创作平台来了!
前端·后端·程序员
CoovallyAIHub3 小时前
搞定边缘AI部署:开源神器RamaLama,让视觉语言模型无处不在
深度学习·算法·计算机视觉
CyberSoma3 小时前
机器人模仿学习运动基元数学编码方法还有用吗?
人工智能·算法·计算机视觉·机器人
CoovallyAIHub3 小时前
英伟达再出「神作」!黄仁勋华盛顿GTC宣布Vera Rubin超级芯片,联手诺基亚进军6G,市值直逼5万亿美元
深度学习·算法·计算机视觉