在不同的编程语言中,冒泡算法都是一种十分经典的算法
其中明显的体现了算法的精神
作者之前虽然知道这个算法的原理
但在上机时却无法清楚的用所学的C语言来表达它的原理和细节
现在特此写一点东西来回顾和重温这个经典的算法
现在给出一个随机的整型数组 11,4,8,9,3,6,18,7
以冒泡法的原理以从小到大排序该数组;
我们要先将11和4对比,因为11>4,所以进行一次互换
这样就是
4,11,8,9,3,6,18,7
再用11和8做对比,11>8,再进行一次互换,如下
4,8,11,9,3,6,18,7
多次过后到这里
4,8,9,3,6,11,18,7
11就小于18了,这里就不能再用11来比了,要将18和7比,将18置于末尾
第一轮循环就完成了,最大的数就沉底了
4,8,9,3,6,11,7,18
下面就要再开始一次循环
以4开始
因为4<8,不进行互换,用8来对比
同理,
用9比3,6,就将3和6拎到前面
像这样
4,8,3,6,9,11,7,18
同上理,用11和7比,将它们互换,就完成了第二轮循环,第2大的数11就沉底了
4,8,3,6,9,7,11,18
同时由于在第一轮的循环中,最大的数已经沉底了,所以这次循环少一次比较
接着开启第3轮循环
依然由4开始,
4<8,再用8来比,经过几次互换后,将3,6再次拎到前面
4,3,6,8,9,7,11,18
这里8<9,不互换,用9来比,将7换到前面
4,3,6,8,7,9,11,18
至此第3个数沉底
下面不再细讲,规律已经十分清楚了
下一次循环后达到这个效果
3,4,6,7,8,9,11,18
现在这个数组就完成了冒泡法的排序;
下面将这个规律概况到程序中去
#include
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
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
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]);
}
}
最后给出一篇关于冒泡法优化的帖子链接供参考
参考方法