算法 排序 【选择排序,冒泡排序】

本文介绍了选择排序和冒泡排序这两种简单的排序算法,它们分别以O(n²)的时间复杂度运行,选择排序通过每趟找出最小元素,冒泡排序则重复交换相邻元素。文章详细阐述了算法原理、代码实现及测试示例,展示了排序过程和稳定性特点。
摘要由CSDN通过智能技术生成

一、排序分类

插入排序:

直接插入排序

折半插入排序

希尔排序

交换排序:

冒泡排序

快速排序

选择排序:

简单选择排序

堆排序

此文我们介绍选择排序,冒泡排序。

二、选择排序

时间复杂度:O(n²)

稳定性:不稳定,因为若第i个元素和另一元素交换,而其关键字大小相同的另一元素在前两者中间,可能导致相对位置改变。

选择排序的基本思想是:

每 i 趟排序都选出一个最小的元素,放在第 i 个位置上;

i 为正整数,由1依次递增到元素个数减1。

代码:

首先用模板写一个交换函数:

template<typename T>//声明一个模板
//typename可以替换成class
//告诉编译器后面代码中紧跟着的T不要报错,T是一个通用数据类型
void mySwap(T& a, T& b)
{
	T temp = a;
	a = b;
	b = temp;
}

然后写选择排序:

template<typename T>
void mySort(T array[], int len)
{
	for (int i = 0; i < len-1; i++)
	{
		int max = i;
		for (int j = i + 1; j < len; j++)
		{
			if (array[max] < array[j])
			{
				max = j;
			}
		}
		if (array[i] != array[max])
		{
			mySwap<int>(array[i], array[max]);
		}
		cout << "这是第" << i + 1 << "趟排序" << endl;
	}
}

由于进行第len-1次排序后,第len次待排序元素只剩最后一个了,也就是说前len-1次排序已经将数组排成了有序数组,

所以写i<len-1即可。

 测试代码:

	int a[] = { 1,2,3,4 };
	int len = sizeof(a) / sizeof(a[0]);	
	cout << len;
	mySort(a, len);
	for (int i = 0; i < len; i++)
	{
		cout << a[i] << endl;
	}

运行截图:

三、冒泡排序

时间复杂度:O(n²)

稳定性:稳定,因为每一趟排序都会把一个元素放在最终位置上。那么关键字大小相同的两个元素,也会按照顺序依次放在最终位置上,不会“篡位”。

冒泡排序的思想是:从后往前(或者从前往后)两两比较相邻元素的值,若为逆序,则交换他们,直到序列比较完。我们称其为第一次冒泡,

结果是将最小的元素交换到待排序列的第一个位置。

每趟排序都把序列中最小的元素放到了序列的最终位置,

这样最多做n-1趟冒泡排序即可排好序。

放一张曾经写的冒泡排序思想:

这里改进一下,

外层:for(int i = 0;i<len-1;i++)

内层:for(int j = 0;j<len-1-i;j++)

代码:

template<typename T>
void myBubbleSort(T array[], int len)
{
	
	for (int i = 0; i < len - 1; i++)
	{
		bool flag = false;
		for (int j = 0; j < len - 1 - i; j++)
		{
			if (array[j] > array[j + 1])
			{
				mySwap<int>(array[j], array[j + 1]);
				flag = true;
			}
		}
		cout << "这是第" << i + 1 << "趟排序" << endl;
		if (flag == false)
		{
			return;
		}
	}

记得使用flag!

因为交换排序会一一遍历,

所以使用flag可以让排序性能更好。

 测试代码:

	int a[] = { 4,3,2,1 };
	int len = sizeof(a) / sizeof(a[0]);	
	myBubbleSort(a, len);
	for (int i = 0; i < len; i++)
	{
		cout << a[i] << endl;
	}

运行截图:

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值