冒泡排序与选择排序
冒泡排序
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)-i
if(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 = 5
minIndex = 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