【数据结构】简单选择排序

目录

一、排序思想

二、算法过程

三、代码实现

四、效率分析

(一)时间复杂度

(二)空间复杂度

五、稳定性分析

六、总结


一、排序思想

每一趟从待排序的元素序列中选出关键字最小(或最大)的元素,顺序放在已排好序的子序列的最前面(或最后面),直到全部元素排序完毕。


二、算法过程

以升序为例,对 n 个元素的数组进行简单选择排序,共需进行 n - 1 趟选择。

第 i 趟选择(i 从 0 开始):

1、设置一个变量 min,记录当前趟最小元素的下标,初始值为 i。

2、从第 i + 1 个元素开始遍历到末尾,逐一与 a[min] 比较。

3、若发现更小的元素,则更新 min 的值。

4、一趟遍历结束后,若 min != i,则将 a[min] 与 a[i] 交换。

5、此时前 i + 1 个元素已经是有序的最小值序列。

示例:

初始序列:{ 49, 38, 65, 97, 76, 13, 27, 49 }

趟数 当前序列 选出最小值 交换位置 结果序列
第1趟 49, 38, 65, 97, 76, 13, 27, 49 13 (下标5) 与 49(下标0) 交换 13, 38, 65, 97, 76, 49, 27, 49
第2趟 13, 38, 65, 97, 76, 49, 27, 49 27 (下标6) 与 38(下标1) 交换 13, 27, 65, 97, 76, 49, 38, 49
第3趟 13, 27, 65, 97, 76, 49, 38, 49 38 (下标6) 与 65(下标2) 交换 13, 27, 38, 97, 76, 49, 65, 49
第4趟 13, 27, 38, 97, 76, 49, 65, 49 49 (下标5) 与 97(下标3) 交换 13, 27, 38, 49, 76, 97, 65, 49
第5趟 13, 27, 38, 49, 76, 97, 65, 49 49 (下标7) 与 76(下标4) 交换 13, 27, 38, 49, 49, 97, 65, 76
第6趟 13, 27, 38, 49, 49, 97, 65, 76 65 (下标6) 与 97(下标5) 交换 13, 27, 38, 49, 49, 65, 97, 76
第7趟 13, 27, 38, 49, 49, 65, 97, 76 76 (下标7) 与 97(下标6) 交换 13, 27, 38, 49, 49, 65, 76, 97

经过 7 趟选择后,序列有序:{ 13, 27, 38, 49, 49, 65, 76, 97 }


三、代码实现

下列代码示例均是排成升序。

cpp 复制代码
#include <stdio.h>

// 打印数组
void Print(int* a, int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
}

// 交换两个元素
void Swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

// 简单选择排序(升序)
void SelectSort(int* a, int n)
{
	for (int i = 0; i < n - 1; i++)
	{
		int min = i;  // 记录最小元素下标
		for (int j = i + 1; j < n; j++)
		{
			if (a[j] < a[min])
			{
				min = j;  // 更新最小值下标
			}
		}
		// 将最小元素交换到第 i 个位置
		if (min != i)
		{
			Swap(&a[i], &a[min]);
		}
	}
}

int main()
{
	int arr[] = { 49, 38, 65, 97, 76, 13, 27, 49 };
	int n = sizeof(arr) / sizeof(arr[0]);

	printf("排序前:");
	Print(arr, n);

	SelectSort(arr, n);

	printf("排序后:");
	Print(arr, n);

	return 0;
}

运行结果:


四、效率分析

(一)时间复杂度

无论初始序列是有序、逆序还是乱序,简单选择排序都需要进行固定的比较次数。

比较次数:

第 1 趟:n - 1 次

第 2 趟:n - 2 次

...

第 n - 1 趟:1 次
总比较次数 = (n - 1) + (n - 2) + ... + 1 = n(n - 1)/2

交换次数:

最多 n - 1 次(每趟都交换),最少 0 次(已有序)。
因此,时间复杂度:O(n²)

(二)空间复杂度

仅使用常数个额外辅助变量(min、tmp 等),与问题规模无关。

因此,空间复杂度:O(1)


五、稳定性分析

简单选择排序是不稳定的排序算法。

反例说明:

初始序列:{ 2, 2, 1 }(带下划线的 2 表示第二个 2,用于区分相同关键字)
第 1 趟:选出最小值 1,与第 1 个元素 2 交换,得到 { 1, 2, 2 }
此时两个 2 的相对位置发生了改变(原第二个 2 现在到了第一个 2 的前面),故不稳定。


六、总结

特性 简单选择排序
排序思想 每趟选最小(大)值放到有序区末尾
时间复杂度 O(n²)
空间复杂度 O(1)
稳定性 不稳定
适用场景 数据量较小,或交换代价远高于比较代价时

感谢阅读,本文如有疏漏不当之处,烦请各位指正。

相关推荐
信奥胡老师1 小时前
B3930 [GESP202312 五级] 烹饪问题
开发语言·数据结构·c++·学习·算法
paeamecium1 小时前
【PAT甲级真题】- Shortest Distance (20)
数据结构·c++·算法·pat考试·pat
aisifang001 小时前
GPT-Image2去偏见技术新突破
人工智能·算法·机器学习
吴可可1231 小时前
点在线上判定与多段线分割
算法·c#
折哥的程序人生 · 物流技术专研2 小时前
《Java 100 天进阶之路》第23篇:缓冲区数据结构 ByteBuffer
java·开发语言·数据结构·后端·面试·求职招聘
吴可可1232 小时前
圆弧多段线离散化采样密度优化
算法·c#
月诸清酒2 小时前
63-260516 AI 科技日报 (X推荐算法开源,核心驱动转向Grok模型)
人工智能·算法·推荐算法
折翅嘀皇虫2 小时前
lock_free_unordered_map
算法
图码2 小时前
矩阵操作优化:从 O(q×n) 到 O(q) 的优雅进阶
数据结构·线性代数·算法·性能优化·矩阵·python3.11