选择排序及优化思路

#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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值