冒泡排序法、选择排序法详解
(一)冒泡排序法
基本思路就是每次将相邻的两个数相互比较,将小头的调到前面。
比如有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; }
本文作者:雨落城
本文链接:https://www.cnblogs.com/maxwell-01/p/15999795.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步