冒泡排序与选择排序
冒泡排序
condition:输入5个数字,冒泡排序,逆序输出
#include<stdio.h>
int main(){int userInput,tmp,i,j,arr[6],flag;flag = 0;for(int i=0;i<5;i++){scanf("%d",&userInput);arr[i] = userInput;}//依次输入五个数字for(int i=0;i<4;i++){//五个数字只需要排序4趟for(int j=0;j<4-i;j++){//每一趟交换次数4-i次 第0趟 4次, 第1趟 3次 if(arr[j] < arr[j+1]){tmp = arr[j];arr[j] = arr[j+1];arr[j+1] = tmp;flag = 1;//存在交换,更新flag}}if(flag == 0){break;}//不存在交换,结束!}for(int i=0;i<5;i++){printf("%d ",arr[i]);}return 0;//逆序输出
}
/*输入n个元素n小于20,冒泡排序,逆序输出*/
#include<stdio.h>
int main(){int n,a[20],flag = 0, i,j,tmp;scanf("%d",&n);for(i=0;i<n;i++){scanf("%d",&a[i]);}for(i=0;i<n-1;i++){for(j=0;j<n-i-1;j++){//一定是(n-1)-iif(a[j]<a[j+1]){tmp = a[j];a[j] = a[j+1];a[j+1] = tmp;flag = 1;}}if(flag == 0){break;}}for(i=0;i<n;i++){printf("%d ",a[i]);}return 0;
}
选择排序
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
/*选择排序*/
//5个数 由小到大 88 66 99 11 23
//1轮,4次
//就是固定第一位,将a0与其他项比较,比较完后保证a0最小或者最大
//2轮,3次
//a1与剩下的每一项比较
```c
//输入5个数字,选择排序,顺序输出
#include<stdio.h>
int main(){int userInput,tmp,i,j,arr[5];for(i=0;i<5;i++){scanf("%d",&userInput);arr[i] = userInput;}//依次输入五个数字for(i=0;i<4;i++){//五个数字只需要排序4趟for(j=i+1;j<5;j++){//这里j不再是交换的次数了,而是剩下数字的角标,因为前面的j就在变化if(arr[i] > arr[j]){//固定每一趟的第一个数字,然后和剩下的数字比较tmp = arr[i];arr[i] = arr[j];arr[j] = tmp;}}}for(i=0;i<5;i++){printf("%d ",arr[i]);}return 0;//顺序输出
}
历史错误:内层循环终止条件错误
交换逻辑错误:一发现arr[i] > arr[j]就交换,导致不必要交换
优化 --> 找到每一趟最小值的下标,每一趟结束后再arr[1]和arr[minIndex]交换
#include<stdio.h>int main() {int userInput, tmp, i, j, minIndex, arr[5];// 依次输入五个数字for (i = 0; i < 5; i++) {scanf("%d", &userInput);arr[i] = userInput;}// 选择排序for (i = 0; i < 5 - 1; i++) { // 进行n - 1趟排序,这里n = 5minIndex = i; // 先假设当前位置的元素就是最小的,记录其索引// 在内层循环中找到真正最小元素的索引for (j = i + 1; j < 5; j++) {if (arr[j] < arr[minIndex]) {minIndex = j;}}// 如果找到的最小元素索引不是当前假设的索引,就进行交换if (minIndex!= i) {tmp = arr[i];arr[i] = arr[minIndex];arr[minIndex] = tmp;}}// 顺序输出for (i = 0; i < 5; i++) {printf("%d ", arr[i]);}return 0;
}
/*输入n个元素n小于20,选择排序,逆序输出*/
#include<stdio.h>
int main(){int n,a[20], i,j,tmp,maxIndex;scanf("%d",&n);for(i=0;i<n;i++){scanf("%d",&a[i]);}for(i=0;i<n-1;i++){maxIndex = i;for(j=i+1;j<n;j++){if(a[j]>a[maxIndex]){maxIndex = j;}if(maxIndex != i){tmp = a[i];a[i] = a[maxIndex];a[maxIndex] = tmp;}}}for(i=0;i<n;i++){printf("%d ",a[i]);}return 0;
}
总结
- 冒泡排序【每趟保证数组最右端最值元素归位】
冒泡排序就是它重复地走访要排序的数列,一次比较两个相邻的元素,根据规则进行一定的交换,保证每一趟完成后,最值数在序列的最右端
核心关注点
总趟数 === number-1【最后一趟已经有序】
相邻元素交换冒泡至最右端
默认趟数从0开始
交换总次数 === (number-1-i) [两两交换,次数=number-1-i]
每趟交换次数== number-1(i===第几趟) - 选择排序【每趟保证数组最左端最值元素归位】
首先固定每趟的第一个元素,假设它是最值
再在这一趟里比较剩下的元素找到最值元素 看是否为第一个假设元素
不是就交换
loop