咸鱼入门——冒泡排序

浅谈冒泡排序

林大计算机咸鱼一枚,爱好计算机,今日是第一次写计算机方面的博客。虽然可能内容简单甚至还有错误,但是希望能够通过此记录自己的成长轨迹。或许这就是我走向成熟的足迹。

冒泡排序是什么?
冒泡排序是简单的排序算法,通过不断地走访元素列,达到没有元素需要交换。
在每一次排序中,比较相邻两个元素,如果大小关系不同于想要的,就交换。这样的直观感受是,大数像石头一样沉淀,小数像泡泡一样“浮出水面”,因此得名“冒泡排序”。
实现原理:
给定N个数,那么它最多需要执行N-1次(因为最后一个一定不需要再次排列)循环,每次循环是一轮。如果某一轮中已经出现了没有交换,则可以提前结束。因此需要一个flag变量,记录循环状态。
在每一轮循环中,从第一个数开始,与下一个数进行比较。一直到上一次沉底的元素。上一次沉底的元素一定不需要排列,因为它一定会是最大的。
Q&A 为什么需要两层循环?
不少同学在问,上课幻灯片里面为什么要有两层循环?内层可以看懂,外层似乎难以理解。
其实,解答此问题,只需看一看我们想做什么。因为代码就是对想做的事情的一种描述。
我们想要在每一轮循环实现冒泡,怎么控制每一轮呢?当然,第一个循环——外面那层。我们知道,最不好的情况是原数和目标数恰恰相反,这样运算次数最多。因为每一次,只能保证让一个最大的数沉底。所以,剩最后一个数的时候不用排,一定是最小的,最多一共需要N-1次循环。怎样表示?for(times=0;times<=N-1;times++)即可。这就是第一层循环。当然,如果需要flag判断是否提前终止,用while也可以。
然后就是大家熟悉的第二层循环了,已经沉底的数不去管他。所以循环次数可以确定。
图解
为什么需要两层循环?Round是外层循环,下箭头连接的是内层循环。
冒泡排序的代码实现

void Array_Sort (int a[],int N)
{
	int times=0,i=0,flag=0;
	int temp;
	while((times<N-1&&(flag==0)))
	{
		flag=1;
		for(;i<N-times-1;i++)
		{
			if(a[i]>a[i+1])
			{
			  flag=0;
			  temp=a[i];
			  a[i]=a[i+1];
			  a[i+1]=temp;
			}
		}
		times++;
		i=0;
	}
}

其中,int a[]是存放数据的数组,N代表了数组的大小。flag是判断是否进行循环的条件:0则进行,1不进行。里面对flag的改变就是这个思想。temp用于交换(也可以在写一个swap函数)。当times小于N-1时(不用N,因为N-1次以后剩下一个没有排列好的一定是最小的了),之后进行冒泡,如果大,下沉。
这里容易出现的一个错误就是i<N-times,忘记了减一。这会导致第一次循环中,访问了不存在的空间。所以结果可能会出错。
我犯了一个弱智错误,就是for循环之后重复使用的变量i没有重置。
时间复杂度
最好情况:本来就是排好的,一趟即可。所以O(n)=n。
最坏情况:上来是反着的。O(n)=n^2。
所以,平均时间复杂度是O(N)=n^2。
第一次写博客,可能错误超级多,还望包涵!
2018.11.3 星期六
#1

猜你喜欢

转载自blog.csdn.net/qq_43208925/article/details/83684040