选择排序从小到大排序:一开始从0~n-1区间上选择一个最小值,将其放在位置0上,然后在1~n-1范围上选取最小值放在位置1上。重复过程直到剩下最后一个元素,数组即为有序。
动图描述:
#include <iostream>
#include <time.h>
#include <vector>
#include <ostream>
using namespace std;
#define RANDOM_NUM 10
// 随机生成RANDOM_NUM 个数
void RandomNum(vector<int>& v)
{
v.clear();
for (uint16_t i = 0; i < RANDOM_NUM; ++i)
{
int num = rand();
v.push_back(num);
}
}
// 针对vector重载<<用于输出vector的元素
template<typename T>
ostream& operator<<(ostream& cout,vector<T>& v)
{
int n = v.size();
for (int i = 0; i < n; ++i)
{
cout << v[i] << " ";
}
return cout << std::endl;
}
// 选择排序(外层for:[0,n-1) 内层:记录当前最小值i(下标),从后续[i + 1,n)中选出最小值,和i交换)
// 时间复杂度为最好、最坏均为 O(n^2) : 两层for循环,总共需要比较(1+2+..+ n - 1)次;即 n * (n - 1) / 2
// 空间复杂度 : 只用到常量个临时变量,所以为O(1)
// 稳定性:从后续序列中选出最小的下标,和当前交换下标i交换,如果当前i和最小下标minIndex之间存下标j,使得在v[i] == v[j],则会造成
// i和minIdx交换后,造成元素v[j]在v[i]后面了,所以是不稳定的
void SelectSort(vector<int>& v)
{
int n = v.size();
if (n <= 1) return;
for (int i = 0; i < n - 1; ++i)
{
int minIdx = i;// 每趟初始最小值为第一个(交换下标)
for (int j = i + 1; j < n; ++j)// 遍历剩下的
{
if (v[j] < v[minIdx]) minIdx = j;// 遇到较小值则重新复制最小下标
}
if (i != minIdx)// 是否初值是最小
{
int tmp = v[i];
v[i] = v[minIdx];
v[minIdx] = tmp;
}
}
}
int main()
{
srand(unsigned(time(NULL)));
vector<int> v;
// 选择排序
RandomNum(v);
std::cout << v;
SelectSort(v);
std::cout << v;
return 0;
}