欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

气泡排序、选择排序详解

最编程 2024-04-19 08:43:39
...

(一)冒泡排序法

   基本思路就是每次将相邻的两个数相互比较,将小头的调到前面。

   比如有6个数:9,8,5,4,2,0;

第一次: 将9与8进行比较,9比8大,调换次序。变为 8,9,5,4,2,0

第二次:将9与5进行比较,9比5大,调换次序。变为8,5,9,4,2,0

第三次:将9与4进行比较,9比4大,调换次序。变为8,5,4,9,2,0

第四次:将9与2进行比较,9比2大,调换次序。变为8,5,4,2,9,0

第五次:将9与0进行比较,9比0大,调换次序。变为8,5,4,2,0,9

 

可以发现走完一整趟,9 沉到最下面了。注意此处总共比较了5次。6个数,比较5次。同理,n个数,第一趟,比较n-1次;

经过第一趟,9放到最下面了,就已经说明9是最大的数字了。

 

还没结束了..这只是第一趟,还有第二趟了!

现在6个数变为8, 5 ,4, 2 ,0 , 9,继续重复第一步的两两比较

第一次,将8与5进行比较,8比5大,调换次序。变为5,8,4,2,0,9;

第二次,将8与4进行比较,8比4大,调换次序。变为5,4,8,2,0,9;

第三次,将8与2进行比较,8比2大,调换次序。变为5,4,2,8,0,9;

第四次,将8与0进行比较,8比0大,调换次序。变为5,4,2,0,8,9;

//第五次,还需要比较8和9吗? 不需要了,因为第一趟的时候,9与每个数字都比较过了,所以这一次不用比较了。

 

可以发现,走完第二趟,8第二大的数字沉到倒数第二的位置了。注意此次比较了4次。6个数,第二趟,比较了4次。同理,n个数,第j趟,比较了n-j次

 

还没结束了..还有第三趟了!

现在6个数变为5,4,2,0,8,9 继续重复第一步的两两比较

第一次,将5与4进行比较,5比4大,调换次序。变为4,5,2,0,8,9

第二次,将5与2进行比较,5比2大,调换次序。变为4,2,5,0,8,9

第三次,将5与0进行比较,5比0大,调换次序。变为4,2,0,5,8,9

 

还没结束了..还有第四趟了!

现在6个数变为4,2,0,5,8,9 继续重复第一步的两两比较

第一次,将4与2进行比较,4比2大,调换次序。变为2,4,0,5,8,9

第二次,将4与0进行比较,4比0大,调换次序。变为2,0,4,5,8,9

 

还没结束了..还有第五趟了!

现在6个数变为2,0,4,5,8,9 继续重复第一步的两两比较

第一次,将2与0进行比较,2比0大,调换次序。变为0,2,4,5,8,9,

OK 结束!

 

 

 

结论:如果有n个数,则要进行n-1趟比较,在第一趟中进行n-1次两两比较,在第j趟中进行n-j次两两比较。

下面看代码如何实现?

 

#include<stdio.h>
int main()
{
    int a[10];
int t; printf(
"请输入10个数\r\n"); for (int i = 0; i < 10; i++) { scanf("%d", &a[i]); } printf("\n"); for (int i = 0; i < 9; i++) //总共进行9趟两两比较 { for (int j = 0; j < 9 - i; j++) //第一趟,总共进9次两两比较 { if (a[j] > a[j + 1]) { t = a[j]; a[j] = a[j + 1]; a[j + 1] = t; } } } printf("该10个数从小到大顺序为:\r\n"); for (int i = 0; i < 10; i++) { printf("%d ", a[i]); } return 0; }

 

 

==================================================================================================================================================================================================================================================  (二)选择排序法

   

             这种排序方法,思路更为清晰,更为简单,就是先假定第一个数为最大值,然后在依次与后面的数比较,如果后面有别的数比它更大,那么交换两个数。

直到最后交换完毕。下面请看例子。

          假设数组有6个数据:5,7 ,2,11 ,9,3;

         我们用一个变量max 存储当前最大的数的下标

 第一步假定5是最大的数,max=1; 然后,比较5与7的大小,7比5大,于是max=2;

 第二步,比较7与2的大小,7比2大,于是max不变,max=2;

第三步,比较11与7的大小,11比7大,于是max 的头衔变为11的下标。max=4

第四步,比较9与11的大小,11比9大,max=4,不变;

第五步,比较3与11的大小,11比3大,max=4,不变;

 

  到这里,第一轮比较完了,发现max的头衔停留在了11上面,有点打擂赛的味道,然后将当前max的下标所对应的值,即11 与5对调。

我们发现,6个数,要比较5次。

 

 

    此时6个数的次序变为 11,7,2,5,9,3;我们已经把最大的数放到了第一位;

接下来开始第二趟,确定第二大的数,并且放到第二位

第一步,假定7是最大的数,max=2; 然后,比较7与2的大小,7比2大,于是max=2;

第二步,比较7与5的大小,7比5大,于是max=2;

第三步,比较7与9的大小,9比7大,于是max=5;

第四步,比较9与3的大小,9比3大,于是max=5;

 

好,至此,我们已经找到了9这个第二大的数了,然后交换9与7的位置。现在 此时6个数的次序变为 11,9,2,5,7,3;

 

以此类推,可以发现,第二趟,比较了4次。

下面看看代码实现:

 

#include<stdio.h>
int main()
{
    int i = 0;         //定义一个i并且赋初值为0,i作为数组的下标
    int j = 0;      //定义j并且赋初值为0,j作为找到最大值时所对应的下标
    int max;            //定义一个max,用来保存此次循环中最大值的下标
    int temp;         //定义一个中间变量temp,供以后交换值的时候使用
    int a[]={5,7,2,11,9,3};    //定义了一个6个数的数组,并且初始化
    for(i = 0;i<5;i++)        //n个数要比较n-1轮
    {
        max = i;           //假设此次循环中的最大值就是当前的值   
        for(j = i+1;j<6;j++) //从接下来的一位开始至最后一位,来争夺最大值 的头衔。每轮比较n-1-i次。
        {
            if(a[j]>a[max])    //将假设的当前最大值与后面的值比较
            {
                max = j;     //若后面的值更大,则交换下标
            }
        }
        if(max!= i)       //比较之后如果此次循环中最大值并非当初假设的值
        { 
            temp = a[i];   //将此次循环中的最大值与a[max]交换
            a[i] = a[max];
            a[max] = temp;
        }
    }
    for(i=0;i<6;i++)       //利用for循环将结果依次输出
    {
        printf("%d ",a[i]);
    }
    return 0;
}