冒泡排序-八大排序第二篇

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三个数据。

原文地址:https://www.cnblogs.com/laurarararararara/p/10914705.html