【王道机试】冒泡排序算法详解+例题

1.常见排序算法的时间和空间复杂度

算法平均时间复杂度最好时间复杂度最坏时间复杂度空间复杂度稳定性
冒泡排序O( n 2 n^2 n2)O( n n nO( n 2 n^2 n2)O( 1 1 1)稳定
快速排序O( n l o g n nlogn nlogn)O( n l o g n nlogn nlogn)O( n 2 n^2 n2)O( n l o g n nlogn nlogn)不稳定
归并排序O( n l o g n nlogn nlogn)O( n l o g n nlogn nlogn)O( n l o g n nlogn nlogn)O( l o g n logn logn稳定
堆排序O( n l o g n nlogn nlogn)O( n l o g n nlogn nlogn)O( n l o g n nlogn nlogn)O( 1 1 1)不稳定
希尔排序O( n l o g n nlogn nlogn)O( n 1.3 n^{1.3} n1.3)O( n 2 n^2 n2)O( 1 1 1)不稳定

注意,对于冒泡排序,最坏的情况就是完全逆序,此时空间复杂度为 O ( n ) O(n) O(n)

2.冒泡排序

1)算法流程

#include<stdio.h>
void swap(int &a,int &b);
int main()
{
	int a[4]={5,6,3,1};
	for(int i = 0;i<4;i++)
		for(int j=0;j<4-i-1;j++if(a[j]>a[j+1])
				swap(a[j],a[j+1];
	return 0;
}
void swap(int &a,int &b)
{
	int temp=a;
	a = b;
	b = temp;	
}

冒泡排序的基本思想就是两两比较并按照规定交换,先确定数组中最后一个数的位置,也就是最大(或最小)的数。然后再一轮从头开始两两比较,确定倒数第二个位置的数字,依次类推,直到数组中的第一个数确定好,整个数组就是有序的了。
e.g: 5 6 3 1(期望正序:1 3 5 6—> a [ j ] < a [ j + 1 ] a[j]<a[j+1] a[j]<a[j+1]
step1: 5与6比较,满足正序,不调整。整个数组:5 6 3 1
step2: 6与3比较,不满足正序,交换:5 3 6 1
step3: 6与1比较,不满足正序,交换:5 3 1 6
可以看到经过一轮交换,最大的数6到了数组的最后一个位置。
第二轮比较(从头开始)
step4: 5与3比较,不满足正序,交换:3 5 1 6
step5: 5与1比较,不满足正序,交换:4 1 5 6
注意,此时不需要再将5与6比较,因为上一轮我们已经确定了数组最后一个位置的数(也就是全局最大的数),再比较也肯定不会产生交换动作,所以内层循环结束条件是j<n-i-1 ,减1是为了a[j+1]不越界。
第三轮比较(从头开始)
step6: 4与1比较,不满足正序,交换:1 4 5 6
因为前两轮我们已经确定了最后两个数字的位置且不会再改变了,所以没有接着往下比较的必要,此时倒数第三个位置的数字也确定了下来。
所以最后只剩下第一个位置,也自然的就确定了下来:1 4 5 6
排序结束。

2)例题:对输入的n个数进行排序

在这里插入图片描述

样例输入:

4
1 4 3 2

样例输出:

1 2 3 4

来源:

2006华中科技大保研机试真题

思路分析:

  1. 复杂度分析

    时间限制是1s,所以数量级最大为1000万级别,因为题目中的n取值范围不大于100,所以即使采用O( n 2 n^2 n2)的算法,如冒泡排序,时间复杂度最多也只是一万,符合要求。
    内存限制32M,因为冒泡排序最坏即完全逆序的情况下的空间复杂度为 O ( n ) O(n) O(n),所以最大内存占用: 100 ∗ 32 b i t 100*32bit 10032bit(申请一个 i n t int int n [ 100 ] n[100] n[100]的数组空间),也是符合要求的,所以本题用最简单的冒泡排序也是可以顺利通过的。

#include<stdio.h>
void swap(int &a,int &b)
{
	int temp=a;
	a = b;
	b = temp;	
}
int main()
{
	
	int a[103],n;
	while(scanf("%d",&n)!=EOF)
	{
		for(int i=0;i<n;i++)
		{
			scanf("%d",&a[i]);
		}
		//冒泡排序 
		for(int i=0;i<n;i++)
			for(int j=0;j<n-i-1;j++)
			{
				if(a[j]>a[j+1])
					swap(a[j],a[j+1]);
			}
		for(int i=0;i<n;i++)
			printf("%d ",a[i]); 
		printf("\n");
	}
	return 0;
 } 

结果:
在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值