选择排序
代码
C语言代码:
#include <stdio.h>
void selection_sort(int arr[], int n) {
for (int i = 0; i < n-1; i++) {
int min_idx = i;
for (int j = i+1; j < n; j++) {
if (arr[j] < arr[min_idx]) {
min_idx = j;
}
}
int temp = arr[min_idx];
arr[min_idx] = arr[i];
arr[i] = temp;
}
}
int main() {
int arr[] = {64, 25, 12, 22, 11};
int n = sizeof(arr)/sizeof(arr[0]);
selection_sort(arr, n);
printf("Sorted array: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
代码解释
- 初始化:数组
arr是待排序的数组,n是数组的长度。 - 主排序循环:
- 外部
for循环控制每一轮的起始位置,从第0个元素到第n-2个元素。 - 初始化最小值索引
min_idx为当前起始位置i。 - 内部
for循环遍历起始位置后面的所有元素,找到最小值,并更新min_idx。 - 找到最小值后,交换当前起始位置元素和最小值元素。
- 外部
- 结果输出:排序完成后,输出排序后的数组。
示例运行
假设输入数组为 {64, 25, 12, 22, 11}:
- 初始状态:
{64, 25, 12, 22, 11} - 第一次外部循环(i=0):
- 找到最小值11,索引为4,交换64和11:
{11, 25, 12, 22, 64}
- 找到最小值11,索引为4,交换64和11:
- 第二次外部循环(i=1):
- 找到最小值12,索引为2,交换25和12:
{11, 12, 25, 22, 64}
- 找到最小值12,索引为2,交换25和12:
- 第三次外部循环(i=2):
- 找到最小值22,索引为3,交换25和22:
{11, 12, 22, 25, 64}
- 找到最小值22,索引为3,交换25和22:
- 第四次外部循环(i=3):
- 当前剩余部分已经有序,无需交换:
{11, 12, 22, 25, 64}
- 当前剩余部分已经有序,无需交换:
最终结果:{11, 12, 22, 25, 64}
时间复杂度分析
选择排序的时间复杂度主要取决于两层循环的执行次数。
- 最优时间复杂度:,即使数组已经有序,仍需进行 次比较。
- 最坏时间复杂度:,在最坏情况下,执行相同数量的比较和交换操作。
- 平均时间复杂度:,无论数组初始顺序如何,执行次数基本一致。
空间复杂度分析
选择排序是一种原地排序算法,不需要额外的辅助空间,空间复杂度为 。在本实现中,我们仅使用了几个额外的变量(i, j, min_idx, temp),因此空间复杂度保持为常数级别。
优缺点
优点:
- 简单易实现。
- 原地排序,空间复杂度低。
- 不依赖于初始数据顺序,性能稳定。
缺点:
- 时间复杂度较高,尤其是对大规模数据,效率较低。
- 不稳定排序算法,可能改变相同元素的相对顺序。
适用场景
选择排序适用于以下场景:
- 数据量较小的排序。
- 需要一个简单且易于理解的排序算法时。
- 学习和教学用途,以理解基本的排序原理。
总结
选择排序是一种简单直观的排序算法,通过反复选择剩余元素中的最小值,将其放到已排序部分的末尾来实现排序。尽管其时间复杂度较高,但在特定场景下,特别是数据量较小时,选择排序仍然是一个有效的选择。