冒泡排序和选择排序--C语言

本文详细介绍了冒泡排序和选择排序的原理,包括比较过程、举例说明和代码实现。两种排序算法均具有O(n^2)的时间复杂度,但冒泡排序稳定,而选择排序不稳定,因其交换不保证相邻。

冒泡排序(升序):

设计思想:

每两个相邻的数进行比较,大的往后走

详细过程:

例:99 ,100, 88 ,80 ,100, 90, 77, 22, 33, 90

第一遍:

99与100比较,100大,继续向后走,

100与88比较,100大,100与88交换一下位置,继续向后走

100与80比较,100大,100与80交换一下位置,继续向后走

100与100比较,相等,不需要管,继续向后走(这里你也可以交换,不过都相等了,交换也是无效操作,浪费时间)

100与90比较,100大,100与90交换位置,继续向后走

100与77比较,100大,100与77交换位置,继续向后走

...

第一遍结束后的结果:99,88,80,100,90,77,22,33,90,100

我们发现,最大的一个100到了最后的位置

第二遍:

99与88比较,99大,99与88交换位置,继续向后走

99与80比较,99大,99与80交换位置,继续向后走

99与100比较,100大,不交换,继续向后走

100与90比较,100大,100与90交换位置,继续向后走

100与77比较,100大,100与77交换位置,继续向后走

...

第二遍结束的结果:88,80,99,90,77,22,33,90,100,100

我们发现,除去第一遍冒出来的最大的100外,剩下的最大的数100也冒出来了,并最终停在了倒数第二个位置

第三遍:

大家可以自己尝试一下,我在这里就直接写结果了

结果:80,88,90,77,22,33,90,99,100,100

我们发现第三遍出去前两遍冒出来的最大的两个100外,剩下的数中最大的99也冒出来了,并停在了倒数第三个位置

...

总结:

根据上述过程,我们可以发现,我们每一遍遍历过程都会有一个最大的数冒出来,并且我们下一遍遍历就不需要管这一遍冒出来的数了

代码实现:

void BubbleSort(int* arr, int len)
{
	int tmp;//中间值,用于交换
	for (int i = 0; i < len - 1; i++)//遍历的次数
	{
		for (int j = 0; j < len - i - 1; j++)
		{
			if (arr[j+1] < arr[j])
			{
                //交换
				tmp = arr[j+1];
				arr[j+1] = arr[j];
				arr[j] = tmp;
			}
		}
	}
}

算法特性:

时间复杂度O(n^2),空间复杂度O(1),稳定

选择排序(升序):

设计思想:

每次都从待排序中选出最小的一个和待排序的第一个数据交换

详细过程:

例:99 ,100, 88 ,80 ,100, 90, 77, 22, 33, 90

首先,我们需要找到最小的值,所以我们需要定义一个值保存这个最小值,还要用在这个值跟待排序的第一个数据交换,所以我们需要的是保存这个最小值的下标(minIndex)直接初始化为待排序数组的第一个值的下标

第一遍:

minIndex=0;99与100比较,99小,继续向后走

99与88比较,88小,让minIndex=2(88所在的下标),继续向后走

88与80比较,80小,让minIndex=3(80所在的下标),继续向后走

80与100比较,80小,继续向后走

...

最后我们发现minIndex=7(22所在的下标),然后我们再把这个值跟第一个值交换就好了。

但是这时候我们还有一种特殊情况,就是我们待排序数组的第一个值就是最小值时,就不要将二者交换了,因为二者本就在同一个位置

结果:22,100,88,80,100,90,77,99,33,90

由此可知,我们每一遍都会选出一个最小值,所以每次循环后都会选出来这个最小值并放在待排序的第一个位置上,所以我们下次循环就不需要管这个值了。

第二遍:

minIndex=1;100与88比较,88小,minIndex=2(88所在的下标),继续向后走

88与80比较,80小,让minIndex=3(80所在的下标),继续向后走

80与100比较,80小,继续向后走

...

结果:22,33,88,80,100,90,77,99,100,90

第三遍:

...

结果:22,33,77,80,100,90,88,99,100,90

...

代码实现:

void SelectSort(int* arr, int len)
{
	int minIndex;//最小值的下标
	int tmp;
	for (int i = 0; i < len - 1; i++)
	{
		minIndex = i;
		for (int j = i+1; j < len; j++)
		{
			if (arr[j] < arr[minIndex])
			{
				minIndex = j;
			}
		}
		if (minIndex != i)
		{
			tmp = arr[minIndex];
			arr[minIndex] = arr[i];
			arr[i] = tmp;
		}
	}
}

算法特性:

时间复杂度O(n^2),空间复杂度O(1),不稳定

总结:

冒泡排序和选择排序都是简单排序,时间复杂度都是O(n^2),但冒泡排序是相邻的两个交换,所以它稳定,而选择排序是最小的值与待排序的第一个值交换,并不一定相邻,所以不稳定

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪星猫宇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值