C++入门手写冒泡排序

/* Note:Your choice is C IDE */
#include "stdio.h"
#define MAX 100
struct slist
{
    
    
	float a[MAX];
	int len;
};
//冒泡排序
void fun(struct slist *s)
{
    
    
	int i,j,flag=0; //i代表循环的趟数  j代表内侧比较的下标
	float t;
	for(i=1;i<s->len;i++)
	{
    
    
		//每趟排序开始
		flag=0;
		for(j=0;j<s->len-i;j++)
		{
    
    
			if(s->a[j]>s->a[j+1])
			{
    
    
				t=s->a[j];
				s->a[j]=s->a[j+1];
				s->a[j+1]=t;
				flag=1;  //1 代表 交换
			}	
		}	
		if(flag==0)
		{
    
    
			break;
		}
	}
	for(i=0;i<s->len;i++)
	{
    
    
		printf("%.2f\t",s->a[i]);	
	}
}

void main()
{
    
    
	int i;
  	struct slist s;
  	s.len=0;
  	for(i=0;i<5;i++)
  	{
    
    
  		printf("请输入第%d个元素:",s.len+1);
  		scanf("%f",&s.a[s.len]);
  		s.len++;	
  	}
  	fun(&s);
}

冒泡排序个人觉得是纯手写中最简单的一个排序

它的原理也很好理解,两个循环,外侧循环控制的是循环次数,正常情况下都是从1开始排n-1次,排到倒数第二次的时候,整个数据队列其实已经全部排完了,最后一个没有必要在拿出来一次了,因为没有数据可以和它排了

里面的循环控制每一次排序的具体操作,之所以内侧循环的结束条件是总数减已排序的次数,是因为每一次结束排序之后,在整个数据队列的后面一定会产生一个最终排序,比如 4 5 2 7 6 8 6 9 这队数据,要求从大到小排序,这时在经历完第一次排序之后,2一定会被排在最后,而且就是它的最终位置,第二次确定的是4,其他的数也是这样依次类推

代码中的flag是一个优化,主要的作用就是在排序进行中,用来标识这一次从头开始排序时,内部是否发生了交换,如果交换了那就标为1,标识数据正在正常的经历排序且排序未完成,而如果没有发生交换,且还是从头开始的,那就还是0,表明真个数据串没有发生交换,说明数据已经有序了,后面的多余次数已经不需要了

下面是常见理解误区,可以不看

刚入门编程的朋友可能会像一个问题为什么外侧开始是1 ,内侧是 0 ,其实这个是冒泡排序本身的最优解,其实不止是这两个数,其他的参数也是这样,虽然可以写别的,但是会出现问题的,大家可以自己慢慢想一想,动手改一改,就会发现,上面的这个代码中的各项参数解决了很多的问题

我任然用4 5 2 7 6 8 6 9 这串数据结合上面的代码给大家举例,总共8个数,从小到大排,要做7次排序,第8次没必要再对仅剩下的一个数据做一次排序了原因我上面说了,做第一次循环的时候,外侧的i是1,内侧的j是0到6,6是总数8减外侧1再减去数组下标边界得来的,数据从4开始比8-1次,恰好比到倒数第二个6那个位置的时候8-1次结束,8和9也在最后一次中比完了,注意是8,不是6,因为排序中就会换位置,第一次之后9保留在了最后,第二次也是这样的操作,只是i成了2,j成了0到5,总计比6次,比到第一次之后8的位置第二次刚好结束,8也在第二次的最后一个比较中被确定下来在倒数第二个

之后的我就不一一细说了,都是一样的,我最后要借此例子说的就是可能还有人没理解为什么是n-1次,大家想想如果真的要n次,而不是n-1,那么在排第n次的时候,4 5 2 7 6 8 6 9 在经历了n-1次之后已经变成了2 4 5 6 6 7 8 9,外侧的i变成了8,内侧的j是0到-1????这个返回大家不觉得反人类吗???

这个时候连程序都奔溃了,跟别说排序了,这个时候可能就有人说了那我把内侧的jlen-i变成jlen不就完了??

那就又会出现一个和现在重叠的问题,就那第一次来说,比完7次9以及到最后了,你不减数组边界的1,再拿9出来比???有意义吗???它和谁比啊?

那又有人说,9是第一次的结果,它后面肯定没数据啊,第二次的时候不就是有8和9了吗,那么问题来了,之后的是有数据,但是第二次、第三次…之后的都是这个样子,将后面以确定的数据在拿出来比一遍????这只是8个数,那要是正儿八经的生产环境下一串数据上万,冒泡排序,本省的运算就很费事了,你不怕服务器内存消耗太大崩了???

而且大家,想一想照这样的逻辑来说,那那次只是多了一次而已,简直就是鸡助

言归正传,就算不考虑其他的任何问题,我们就当真的可以排到第8次,那么按照从小到大的排序流程来说第八次时数据的开头应该2,后面的7个数7次排序完成了,2在比一次???和谁比???有意义?????

我还碰见很多杠精,跟我说他想动i=1为i=0,我的妈呀,这种想法就可怕了,这和不减下标边界一个意思,都会导致内侧的次数多一次鸡助,不想多排里面就要因为i变为0而多减1

总之,我碰到的奇葩真的是海了去了,多的我都不想说其他的了,看我这篇博文的伙伴们也别多想了,就记住我上面的代码就是最优解就行了

猜你喜欢

转载自blog.csdn.net/dudadudadd/article/details/112562381