选择排序(Selection Sort)是一种简单直观的排序算法。它的核心思想非常直接:在未排序的序列中不断寻找最小(或最大)元素,将其放到已排序序列的末尾
举例:
我们以升序排序数组 [64, 25, 12, 22, 11] 为例:
- 第1趟排序 :
- 在
[64, 25, 12, 22, 11]中找到最小值11。 - 将
11与未排序区首元素64交换。 - 结果:
[11, 25, 12, 22, 64]
- 在
- 第2趟排序 :
- 在剩余未排序部分
[25, 12, 22, 64]中找到最小值12。 - 将
12与未排序区首元素25交换。 - 结果:
[11, 12, 25, 22, 64]
- 在剩余未排序部分
- 第3趟排序 :
- 在剩余未排序部分
[25, 22, 64]中找到最小值22。 - 将
22与未排序区首元素25交换。 - 结果:
[11, 12, 22, 25, 64]
- 在剩余未排序部分
- 第4趟排序 :
- 在剩余未排序部分
[25, 64]中找到最小值25。 25位置不变(或者与自己交换)。- 结果:
[11, 12, 22, 25, 64]
- 在剩余未排序部分
- 结束 :最后一个元素
64自动归位,排序完成
代码实现:
cpp
#include <stdio.h>
// 交换两个元素的值
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
// 选择排序主函数
void selectionSort(int arr[], int n) {
// i 代表已排序区间的边界,也是未排序区的起始位置
for (int i = 0; i < n - 1; i++) {
int minIndex = i; // 假设当前位置 i 的元素是最小的
// 在未排序区间 [i+1, n-1] 中寻找真正的最小值
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j; // 更新最小值的索引
}
}
// 将找到的最小值与未排序区的第一个元素交换
if (minIndex != i) {
swap(&arr[i], &arr[minIndex]);
}
}
}
// 打印数组
void printArray(int arr[], int n) {
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
// 测试代码
int main() {
int data[] = {64, 25, 12, 22, 11};
int n = sizeof(data) / sizeof(data[0]);
printf("原始数组: ");
printArray(data, n);
selectionSort(data, n);
printf("排序后数组: ");
printArray(data, n);
return 0;
}
算法优化策略:
标准的选择排序每次只能确定一个最小值。我们可以对其进行优化:在每一轮遍历中,同时找出未排序区间的最大值和最小值,分别放到当前区间的左右两端。这样可以在理论上将遍历次数减少一半。
关键注意点 :如果最大值恰好在未排序区间的起始位置(即最小值要交换到的位置),那么在交换最小值后,最大值的位置会发生改变,需要特殊处理更新 maxIndex。
