排序 - 简单选择排序

算法

简单选择排序法(Simple Selection Sort)就是通过n - i次关键字间的比较,从 n - i + 1个记录中选出关键字最小的记录,并和第 i (1 <= i <= n)个记录交换。

代码

// 对顺序表 L 作简单选择排序
void SelectSort(PSqlist L)
{
	int i, j, min;
	for (i = 1; i < L->length; i++)
	{
		// 将当前下标定义为最小值下标
		min = i;
		// 循环之后的数据
		for (j = i + 1; j <= L->length; j++)
		{
			// 如果有小于当前最小值的关键字
			if (L->r[min] > L->r[j])
				// 将此关键字的下标赋值给min
				min = j;
		}
		// 若min不等于i,说明找到最小值,交换
		if (i != min)
			swap(L, i, min);
	}
}

理解

首先我们提供了一个用于排序用的顺序表结构,
以及它的构造函数:使用一个vector来对数组里的数据进行初始化

// 用于要排序数组的个数最大值,可以根据需要修改
#define MAXSIZE 10

typedef struct
{
	int r[MAXSIZE + 1];	// 用于存储要排序数组,r[0]用作哨兵或临时变量
	int length;			// 用于记录顺序表的长度
	SqList(std::vector<int>& arr)
	{
		// 首先将长度置为0
		length = 0;
		// 数组下标首先从1开始
		int index = 1;
		for (auto i : arr)
		{
			r[index] = i;
			length++;
			index++;
			if (index > MAXSIZE)
				break;
		}
	}
}SqList,*PSqlist;

接着提供了一个交换函数

// 交换L中数组r的下标为i和j的值
void swap(SqList* L, int i, int j)
{
	int temp = L->r[i];
	L->r[i] = L->r[j];
	L->r[j] = temp;
}

然后我们可以再提供一个输出打印函数来检验结果

// 输出数组r中的值
void print(PSqlist L)
{
	assert(L != nullptr);

	for (int i = 1; i <= L->length; i++)
	{
		std::cout << L->r[i] << " ";
	}
	std::cout << std::endl;
}

我们假设待排序的关键字序列是 {9,1,5,8,3,7,4,6,2} ;
对 i 来说:从1循环到8;

当 i = 1 时:
L.r [i] = 9, min 开始是1,然后与 j=2 到 9 比较 L.r [min] 与 L.r [j] 的大小,因为 j = 2 时最小,所以 min=2。最后交换了 L.r [2]与L.r [1]的值,如图所示:
在这里插入图片描述
当 i = 2 时:
L.r [i] = 9,min开始是2,经过比较后,min=9,交换 L.r [min]与L.r [i] 的值。如图所示:
在这里插入图片描述
当 i = 3 时:
L.r [i] = 5,min开始是3,经过比较后,min=5,交换 L.r [min]与L.r [i] 的值。如图所示:
在这里插入图片描述
之后的数据比较和交换完全雷同;
最多经过 8 次交换,就可以完成排序工作。

测试代码

我们可以使用如下代码进行检验:

#include <iostream>
#include <vector>
#include "SortStruct.h"

using namespace std;

int main()
{
	std::vector<int> ar = {9,1,5,8,3,7,4,6,2};
	SqList a(ar);
	std::cout << "原始序列为:" << std::endl;
	print(&a);
	SelectSort(&a);
	std::cout << "排序后:" << std::endl;
	print(&a);

	return 0;
}

运行结果

运行结果如下:
在这里插入图片描述

复杂度分析

从简单选择排序的过程来看,它最大的特点就是交换移动数据次数相当少,这样也就节约了相应的时间。
无论最好还是最差,其比较次数都是一样的多,第 i 趟排序需要进行 n - i 次关键字的比较。
故,
总的时间复杂度为O(n^2) ;
空间复杂度:O(1) ;
稳定性:不稳定

参考资料

【1】程杰. 大话数据结构. 北京:清华大学出版社,2011:2.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值