#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
/*
* 选择排序: —— 不稳定
* 第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,
* 然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。
*
* 选择排序相较于冒泡排序来说,仅仅只是减少了元素交换的次数
*/
void out_vec(vector<int>& vec); //函数的声明式
//选择从小到大,递增排序;所以每次寻找最小值
void select_sort_1(vector<int>& vec)
{
int len = vec.size();
for (int i = 0; i < len - 1; ++i)
{
int min_idx = i; //首先假设未排序部分的第一个元素是最小值
for (int j = i + 1; j < len; ++j)
{
if (vec[j] < vec[min_idx]) //若后面的元素小,则更新最小值下标;
{
min_idx = j;
}
}
swap(vec[i], vec[min_idx]);
out_vec(vec);
}
}
//上述方法一中,每次选择了未排序部分的最小值;能不能进行优化呢?
//——>每次记录未排序序列中的最大值和最小值,然后分别将其插入到前后有序数组;
//循环结束的条件:当最小元素的位置+1 = 最大元素的位置 时,数据已经全部有序!
void select_sort_2(vector<int>& vec)
{
int len = vec.size();
int left = 0; // 记录每一轮的最小值索引
int right = len - 1; // 记录每一轮的最大值索引
while (left < right)
{
int minIndex = left;
int maxIndex = left;
for (int i = left + 1; i <= right; i++)
{
if (vec[i] < vec[minIndex])
{
minIndex = i;
}
if (vec[i] > vec[maxIndex])
{
maxIndex = i;
}
}
// 说明剩下的所有值都相等,无需再交换
if (minIndex == maxIndex)
{
break;
}
// 剩下的数中,保证 a[left] 最小,a[right] 最大
if (left != minIndex)
{
swap(vec[left], vec[minIndex]);
}
// 注意:left == maxIndex 的情况需要进行特殊处理
// 因为经过上面的 if 后,原来的 a[left] 已经交换到了 a[minIndex] 处,
// 所有如果 left 是 maxIndex 的话,就需要更新一下 maxIndex
if (maxIndex == left)
{
maxIndex = minIndex;
}
if (right != maxIndex)
{
swap(vec[right], vec[maxIndex]);
}
// 更新边界
left++;
right--;
//输出每次排序的结果。
out_vec(vec);
}
}
//数组打印函数
void out_vec(vector<int>& vec)
{
for (auto& num : vec)
{
std::cout << num << " ";
}
std::cout << std::endl;
}
int main()
{
vector<int> vec({ 1,4,2,5,67,32,65,23,59,9,64 });
select_sort_1(vec);
std::cout << std::endl << std::endl;
vector<int> vec_1({ 1,4,2,5,67,32,65,23,59,9,64 });
select_sort_2(vec_1);
std::cout << std::endl << std::endl;
system("pause");
return 0;
}
选择排序及优化思路
于 2023-08-09 23:33:31 首次发布