C的冒泡法回顾

版权声明:请尊重每一个人的劳动成果 https://blog.csdn.net/jamenu/article/details/84587723

在不同的编程语言中,冒泡算法都是一种十分经典的算法
其中明显的体现了算法的精神
作者之前虽然知道这个算法的原理
但在上机时却无法清楚的用所学的C语言来表达它的原理和细节
现在特此写一点东西来回顾和重温这个经典的算法

现在给出一个随机的整型数组 11,4,8,9,3,6,18,7

以冒泡法的原理以从小到大排序该数组;
我们要先将11和4对比,因为11>4,所以进行一次互换
这样就是

4118936187

再用11和8做对比,11>8,再进行一次互换,如下

4811936187

多次过后到这里

4893611187

11就小于18了,这里就不能再用11来比了,要将18和7比,将18置于末尾
第一轮循环就完成了,最大的数就沉底了

4893611718

下面就要再开始一次循环
以4开始
因为4<8,不进行互换,用8来对比
同理,
用9比3,6,就将3和6拎到前面
像这样

4836911718

同上理,用11和7比,将它们互换,就完成了第二轮循环,第2大的数11就沉底了

4836971118

同时由于在第一轮的循环中,最大的数已经沉底了,所以这次循环少一次比较

接着开启第3轮循环
依然由4开始,
4<8,再用8来比,经过几次互换后,将3,6再次拎到前面

4368971118

这里8<9,不互换,用9来比,将7换到前面

4368791118

至此第3个数沉底
下面不再细讲,规律已经十分清楚了
下一次循环后达到这个效果

扫描二维码关注公众号,回复: 5767999 查看本文章
3467891118

现在这个数组就完成了冒泡法的排序;
下面将这个规律概况到程序中去

#include <stdio.h>
int main()
{
 int a[10],i,j,k;
 
 printf("请输入数组的各个元素:\n");
 
 for(i=0;i<10;i++)
 {
       scanf("%d",&a[i]);  //从键盘输入数组A的各个元素
 }
 
 for(i=0;i<9;i++)      //最后一个元素后面没有元素了,故只要执行10-1=9次就完成
 {
       for(j=0;j<9-i;j++)   //设置内循换进行比较,每一次循环沉底一个数,故每次循环少1次
       {                          //为9-i次
               if(a[j]>a[j+1])   //当前一个元素比后一个元素大时就互换它们的值
               {
                    k = a[j];    //当不满足条件时,就不互换,自动用下一个大的值向后比较
    
                    a[j] = a[j+1];
    
                    a[j+1] = k;    
                } 
         }
 }                      //通常不需要这么多次循环,这里为了要满足一种一种最坏的,也是时间
 printf("冒泡排序后如下:\n");//和空间复杂都最高的即从大到小的排列情况,相反,若输入1个从
                              //小到大的序列,理论上就不需要执行循环,这也是我们老师提到并讲过的情况,我们必须加以改进
 for(i=0;i<10;i++)
 {
  printf("%5d",a[i]);
 }
}

下面贴出程序的运行截图

在这里插入图片描述

老师在将这个方法时,说要针对我在上一个代码中存在的问题,要像办法解决要用标记来进行判断(也就是我们大的定义中的布尔型变量)
下面给出操作代码

#include <stdio.h>
int main()
{
	int a[10],i,j,k,flag = 1;   //加上一个标记flag
	
	printf("请输入数组的各个元素:\n");
	
	for(i=0;i<10;i++)
	{
		scanf("%d",&a[i]);
	}
	
	for(i=0;i<9;i++)
	{
		
		for(j=0;j<9-i;j++)
		{
			flag = 0;    //在内循环中设这个标记,如果没有发生互换,就设为0
			if(a[j]>a[j+1])
			{
				k = a[j];
				
				a[j] = a[j+1];
				
				a[j+1] = k;	
				
				flag = 1;	//发生互换就设为1			
			}
				
		}
		
		if(flag==0)//最后利用一个分支来始没有交换的时候跳出,这样可以减少计算次数
		{
			break;
		}

	}
	printf("冒泡排序后如下:\n");
	
	for(i=0;i<10;i++)
	{
		printf("%5d",a[i]);
	}
}

现在给出程序运行截图
在这里插入图片描述

但优化的方法并不只有一种,
作者在写这篇帖子时在网上查阅了相关的资料,
找到了一些很好的方法在本站
由于我没有看过数据结构和算法的书籍
我在浏览时感觉被算法淹没,不知所措。
若以后有时间再来续写其他方法,
现在时23点44分,
今天又是新的的一天,我把冒泡排序写成函数
下面是我的操作代码

#include <stdio.h>
void maopao(int a[]);
void put_int_array(int a[],int n);
int scanf_int_array(int a[],int x)int main()       //我喜欢简短的主函数
{
 int a[10],i;
 printf("请输入10个数\n");
 scanf_int_array(a,10); //懒人用输入整型数组函数
 maopao(a)//调用冒泡排序函数
 printf("冒泡排序后为\n");
 put_int_array(a,10);   //懒人用输出数组函数  
}
void maopao(int a[])   //用数组名做参数,将地址传入形参中,使共用内存,这在我的上一片关于指针的帖子里说过,这里把元素进行冒泡排序
{
 int i,j,k;
 
 for(i=0;i<9;i++)
  {
         for(j=0;j<9-i;j++)
         {
               if(a[j]>a[j+1])
               {
                      k = a[j];
    
                     a[j] = a[j+1];
    
                     a[j+1] = k;
                }
          }
  } 
}
void put_int_array(int a[],int n)//一个用于输出整型数组的函数
{
 int i;
 for(i=0;i<n;i++)
 {
        printf("%5d",a[i]);
 }
 
}
int scanf_int_array(int a[],int x)     //一个用于输入整型数组的函数
{
 int c;
 for(c=0;c<x;c++)
 {
        scanf("%d",&a[c]);
 } 
}

下面给出程序运行的截图
在这里插入图片描述

最后给出一篇关于冒泡法优化的帖子链接供参考
参考方法

猜你喜欢

转载自blog.csdn.net/jamenu/article/details/84587723