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。选择排序算法是否到位?

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

相关推荐
yannan201903132 分钟前
【算法】(Python)动态规划
python·算法·动态规划
埃菲尔铁塔_CV算法4 分钟前
人工智能图像算法:开启视觉新时代的钥匙
人工智能·算法
EasyCVR4 分钟前
EHOME视频平台EasyCVR视频融合平台使用OBS进行RTMP推流,WebRTC播放出现抖动、卡顿如何解决?
人工智能·算法·ffmpeg·音视频·webrtc·监控视频接入
linsa_pursuer5 分钟前
快乐数算法
算法·leetcode·职场和发展
小芒果_016 分钟前
P11229 [CSP-J 2024] 小木棍
c++·算法·信息学奥赛
qq_434085908 分钟前
Day 52 || 739. 每日温度 、 496.下一个更大元素 I 、503.下一个更大元素II
算法
Beau_Will8 分钟前
ZISUOJ 2024算法基础公选课练习一(2)
算法
XuanRanDev11 分钟前
【每日一题】LeetCode - 三数之和
数据结构·算法·leetcode·1024程序员节
gkdpjj12 分钟前
C++优选算法十 哈希表
c++·算法·散列表
代码猪猪傻瓜coding12 分钟前
力扣1 两数之和
数据结构·算法·leetcode