C语言数据的组织与处理 整型数组排序 冒泡排序 穷举算法

1.冒泡排序法
现在给大家一个来思考,给你10个质量不同的塑料小球,让你从轻到重依次分开,不用能用称重的方法解决,你能想到用什么办法吗?
冒泡排序(BubbleSort)的基本概念是:依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。
2.冒泡排序的算法设计原理
冒泡排序算法的运作如下:(从后往前)
(1)比较相邻的元素。如果第一个比第二个大,就交换他们两个。
(2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
(3)针对所有的元素重复以上的步骤,除了最后一个。
(4)持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
3.冒泡排序的应用
(1)从小到大排序,
原始待排序数组| 6 | 2 | 4 | 1 | 5 | 9 |
(2)利用冒泡分析过程
①第一趟排序(外循环)
第一次两两比较6 > 2交换(内循环)
交换前状态| 6 | 2 | 4 | 1 | 5 | 9 |
交换后状态| 2 | 6 | 4 | 1 | 5 | 9 |
第二次两两比较,6 > 4交换
交换前状态| 2 | 6 | 4 | 1 | 5 | 9 |
交换后状态| 2 | 4 | 6 | 1 | 5 | 9 |
第三次两两比较,6 > 1交换
交换前状态| 2 | 4 | 6 | 1 | 5 | 9 |
交换后状态| 2 | 4 | 1 | 6 | 5 | 9 |
第四次两两比较,6 > 5交换
交换前状态| 2 | 4 | 1 | 6 | 5 | 9 |
交换后状态| 2 | 4 | 1 | 5 | 6 | 9 |
第五次两两比较,6 < 9不交换
交换前状态| 2 | 4 | 1 | 5 | 6 | 9 |
交换后状态| 2 | 4 | 1 | 5 | 6 | 9 |
②第二趟排序(外循环)
第一次两两比较2 < 4不交换
交换前状态| 2 | 4 | 1 | 5 | 6 | 9 |
交换后状态| 2 | 4 | 1 | 5 | 6 | 9 |
第二次两两比较,4 > 1交换
交换前状态| 2 | 4 | 1 | 5 | 6 | 9 |
交换后状态| 2 | 1 | 4 | 5 | 6 | 9 |
第三次两两比较,4 < 5不交换
交换前状态| 2 | 1 | 4 | 5 | 6 | 9 |
交换后状态| 2 | 1 | 4 | 5 | 6 | 9 |
第四次两两比较,5 < 6不交换
交换前状态| 2 | 1 | 4 | 5 | 6 | 9 |
交换后状态| 2 | 1 | 4 | 5 | 6 | 9 |
③第三趟排序(外循环)
第一次两两比较2 > 1交换
交换后状态| 2 | 1 | 4 | 5 | 6 | 9 |
交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |
第二次两两比较,2 < 4不交换
交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |
交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |
第三次两两比较,4 < 5不交换
交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |
交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |
④第四趟排序(外循环)无交换
⑤第五趟排序(外循环)无交换
⑥排序完毕,输出最终结果1 2 4 5 6 9

(3)参考代码如下:

/* 从低到高排序 */
#include "stdio.h"
void main()
{
    int a[6] = { 6, 2, 4, 1, 5, 9 };
    int temp;
    int i,j;
	for (i = 1; i < 6; i++)
	{
	    for (j = 0; j <6-i ; j++)
	    {
	        if (a[j] > a[j+1])
	        {
	            temp = a[j];
	            a[j] = a[j+1];
	            a[j+1] = temp;
	        }
	    }
	}
	printf("从低到高依次为\n");
	
	for(i=0;i<6;i++)
	printf("%d\t",a[i]);
}

四、生活案例表述及分析
学校要进行歌唱比赛,经过层层筛选,最终选出了10位同学进行总决赛,现在要求做一个程序,输入10个人的参赛得分,按得分的高低,排出第一名到第十名。
1.解题思路描述方法如下:
(1)定义一个10个元素的数组,存储评委打分。
(2)因为要用到10位同学的比赛得分,所以要用数组
(3)在进行排序之前必须先输入10个人的得分
(4)依据得分进行冒泡排序
(5)排序完成输出结果。
2.案例效果图如下:
![在这里插入图片描述]

在这里插入图片描述

/* 利用冒泡排序解决实际问题 */
#include "stdio.h"
void main()
{
    int a[10];       //存放10位同学成绩的数组
    int temp;        //用于两数比较临时存放数据
    int i,j;         //循环变量
    //利用循环输入10位同学得分
    for(i=0;i<10;i++)
    {
    	printf("请输入第%d位同学得分:",i+1);
    	scanf("%d",&a[i]);    	
    }
    //冒泡排序
    for(i=1;i<10;i++)
    {
    	for(j=0;j<10-i;j++)
    	{
    		if(a[j]<a[j+1])
    		{
    			temp=a[j];
    			a[j]=a[j+1];
    			a[j+1]=temp;    			
    		}    		
    	}    	
    }  
    //输出结果
    printf("成绩从高到低依次是:\n");
    for(i=0;i<10;i++)
    {
    	printf("%d\t",a[i]);
    }       
}

穷举的实现
穷举法(Exhaustion),也称枚举法(Enumeration):列举所有可能,逐一试探 。
穷举法求解问题的两个基本要素
1.确定穷举对象和穷举范围
影响算法的时间复杂度、 循环结构实现
2.确定判定条件
符合什么条件才能成为问题的答案、分支结构实现
话不多说直接上题!
二、ACM穷举法实例27——鸡兔同笼 (如下图)
在这里插入图片描述

/* Note:Your choice is C IDE */
#include "stdio.h"
void main()
{
    int i,j;
    for(i=1;i<98;i++)
    {
    	if(2*i+(98-i)*4==386)
    	{
    		printf("鸡%d头\n兔%d只\n",i,98-i);
    	}  	
    	
    }
 }

四、分析上述代码与下述代码的区别

/* Note:Your choice is C IDE */
#include "stdio.h"
void main()
{
    int i,j;
    for(i=1;i<98;i++)
    {
    	if(2*i+(98-i)*4==386)
    	{
    		printf("鸡%d头\n兔%d只\n",i,98-i);
           break;
    	}  	
    	
    }
    
}

五、ACM案例28水仙花数
其中水仙花数定义各个位数立方和等于它本身的三位数。
通过上面已知水仙花数是一个三位数,也就是100到999之间;要求是每位数的立方和等于它本身。
分析:假设要判断的数是num则这上数的个、十、百位的数字应该是:
个位:g=num%10;
S=num/10%10;
B=num/100;
要求满足条件:ggg+sss+bbb==num;
所以用穷举的方法代码如下;

/* Note:Your choice is C IDE */
#include "stdio.h"
void main()
{
    int num;//定义数变量
    int g,s,b;//定义个、十、百位变量名
    printf("水仙共数有:");
    for(num=100;num<=999;num++)//穷举测试
    {
    	g=num%10;      //个位数
    	s=num/10%10;   //十位数
    	b=num/100;     //百位数
    	if(g*g*g+s*s*s+b*b*b==num)   //判断条件
    	{
    		printf("%d\t",num);
    	}    	
    }    
}

六、试分析以下代码与上述代码的区别

/* Note:Your choice is C IDE */
#include "stdio.h"
void main()
{
    int num;//定义数变量
    int g,s,b;//定义个、十、百位变量名
    printf("水仙共数有:");
    for(num=100;num<=999;num++)//穷举测试
    {
    	g=num%10;      //个位数
    	s=num/10%10;   //十位数
    	b=num/100;     //百位数
    	if(g*g*g+s*s*s+b*b*b==num)   //判断条件
    	{
    		printf("%d\t",num);
    		break;
    	}    
    	
    }    
}

猜你喜欢

转载自blog.csdn.net/SqrsCbrOnly1/article/details/91376035