2019-05-23 23:35:32
八大排序第一篇(快速排序)详见2019-04-27文章
1.问题提出与描述
有时我们想让某数组升序排列。不妨设num[1],num[2]...num[n]来表示该数组。可以从第一个元素开始,比较相邻元素。若a[1]大于a[2]时,交换位置。现在比较a[2]和a[3],若a[2]>a[3],互换位置。按照这种逻辑,可以逐个比较相邻的元素,直到列表尾部。第一次处理中,需要n-1次比较。进行n-1次比较时,计数下标i的值从1递增到n-1。每处理一趟,待处理数据元素的集合中的最大值被交换到最右侧。然后集合元素除去当前最大值,接着对剩余元素集合做相同处理。一个大小为n的数组,需要n-1趟处理。
可以观察到,在每趟处理中,当前最大元素被不断向尾部移动,每趟处理完毕,最“轻”的元素就排到队列的第一个位置。这有点像气泡从瓶底向瓶口浮动。因此这种排序算法被称为冒泡排序。(bubble sort)
2.算法描述
(1).将n个元素保存到数组a[n]中
(2).重复第3步,每一趟的值从1递增到n-1,每趟处理中,i的值从1递增到n-1.
(3).如果a[i]和a[i+1],那么
temp=a[i]
a[i]=a[i+1]
a[i+1]=temp;
(4).数组a[]排序完毕。可显示数组元素
3.代码设计
/*冒泡排序*/ #include<stdio.h> int main(){ int i,pass,n; // i计数下标 pass趟数 n数据个数 int a[70],temp; //先开辟长度为70的数组长度,temp为一个临时值 ,交换的中间变量 printf("how many elements?"); scanf("%d",&n); printf("enter the elements: "); for(i=1;i<=n;i++) //利用for循环依次输入数据的元素 scanf("%d",&a[i]); for(pass=1;pass<=n-1;pass++) //外层for循环限制排序数组的最多趟数为n-1趟 { for(i=1;i<=n-1;i++) //内层for循环控制每一趟对数组元素的遍历,i的最大值为n-1,每一趟的最后一次比较时,第n-1与第n个数比较(第一次写的时候,未考虑到这一点) { if(a[i]>a[i+1]) { temp=a[i]; a[i]=a[i+1]; a[i+1]=temp; } } } printf("the sorted elements :"); for(i=1;i<=n;i++) printf("%3d",a[i]); }
4.实现
5.实例分析
初始元素 3 1 6 2 7
第一趟 1 3 2 6 7
第二趟 1 2 3 6 7
第三趟 1 2 3 6 7
第四趟 1 2 3 6 7
6.算法小改进
由算法的思想可知,在每一趟的遍历中,总是把最大的数排列到数组的最右边,所以在每一趟的遍历中,都需要由第一个数遍历到最后一个数,i从1一直指向n-1,即遍历n-1次。这样或导致时间的浪费。所以可以改进为在第一趟遍历时,遍历整个数组,在第二趟遍历时,只需遍历由1到第n-1个数,因为最右边的数已处于最大位置,无需再进行比较。以此类推,即第三趟遍历的时候,需要比较n-3次。由上述规律可以得出,在每次遍历的时候,只需要遍历n-psss(趟数),即可使代码运行更加高效。所以,内层for循环中,i的值每次随着pass的值增大而变化。内层for循环可以优化为
for(i=1;i<=n-pass;i++)
在上述例子中,,第一趟不变。第二趟只需比较 1 3 2 6 四个数据,第三趟比较 1 2 3三个数据。