冒泡算法进行排序
(从小到大)
第一种 类似的选择排序
主要思想:
①标记第一个数
往后一直比较后面的,若出现比标记数小的 进行交换。
②第一个数比较完毕 之后 标记改为第二个数 进行①
#include<stdio.h>
int main() {
int n;//n个数
int index = 0;//标记
int num;//交换中间
printf("enter n num!\n");
scanf("%d", &n);
int a[n], b[n];
for (int k = 0; k < n; ++k) {//循环赋值
scanf("%d", &a[k]);
}
//冒泡算法1
for (int i = 0; i < n; ++i) {//外循环比较数
for (int j = i + 1; j < n; ++j) {//内循环
if (a[j] < a[i]) {//从小到大交换
num = a[i];
a[i] = a[j];
a[j] = num;
}
}
}
for (int l = 0; l < n; ++l) {//输出
printf("%d ", a[l]);
}
printf("\n");
return 0;
}
第二种
主要思想:
① 进行相邻的两个数比较 若出现前面的数比后面的大 则进行交换。 比较交换完成之后 较大数会往后移动,直至移动到最后。注1
② 第一步完成一个数有序(找到排序好的最终位置) 那么循环① n次 就可以完成n个数的有序。
#include<stdio.h>
int main() {
int n;//n个数
int index = 0;//标记
int num;//交换中间
printf("enter n num!\n");
scanf("%d", &n);
int a[n], b[n];
for (int k = 0; k < n; ++k) {//循环赋值
scanf("%d", &a[k]);
}
//冒泡2
for (int m = 0; m < n; ++m) {//外循环次数
index=0;//重置标记
for (int i = 0; i < n; ++i) {//相邻比较
if (a[i] > a[i + 1]) {//前面大交换
num = a[i + 1];
a[i + 1] = a[i];
a[i] = num;
}
}
}
for (int l = 0; l < n; ++l) {//输出
printf("%d ", a[l]);
}
return 0;
}
关于第二种的两种优化
优化1
第二中方法中的注1 位置 一次循环将一个数进行有序化,那么第二次循环的时候就可以不用比较最后一个有序的数。
即代码修改为:
//冒泡2
for (int m = 0; m < n; ++m) {//外循环次数
index=0;//重置标记
for (int i = 0; i < n-m; ++i) {//相邻比较 -m的原因是每执行一次内循环 就有一个数有序
if (a[i] > a[i + 1]) {//前面大交换
num = a[i + 1];
a[i + 1] = a[i];
a[i] = num;
}
优化2
相邻比较时,若出现比较一次一个数据没有进行交换,那么说明相邻的两个数是有序的 全部比较完都没有交换,就是全部都是有序的。
那么优化就可以基于这个,当一次相邻比较之后没有发生交换(设置交换标记index)就可以跳出循环,完成排序。
//冒泡2
for (int m = 0; m < n; ++m) {//外循环次数
index=0;//重置标记
for (int i = 0; i < n-m; ++i) {//相邻比较
if (a[i] > a[i + 1]) {//前面大交换
num = a[i + 1];
a[i + 1] = a[i];
a[i] = num;
index = 1;//交换标记
}
// if (index == 0) {//若循环一次未发生交换则有序
// printf("1\n");
// break;
// }
}
if (index == 0) {//若循环未发生交换则有序
// printf("2\n");
break;
}
}