冒泡排序与选择排序超详细讲解

冒泡排序与选择排序

冒泡排序

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;
}

img

选择排序

首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

/*选择排序*/
//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;
}

img

总结

  • 冒泡排序【每趟保证数组最右端最值元素归位】
    冒泡排序就是它重复地走访要排序的数列,一次比较两个相邻的元素,根据规则进行一定的交换,保证每一趟完成后,最值数在序列的最右端
    核心关注点
    总趟数 === number-1【最后一趟已经有序】
    相邻元素交换冒泡至最右端
    默认趟数从0开始
    交换总次数 === (number-1-i) [两两交换,次数=number-1-i]
    每趟交换次数== number-1(i===第几趟)
  • 选择排序【每趟保证数组最左端最值元素归位】
    首先固定每趟的第一个元素,假设它是最值
    再在这一趟里比较剩下的元素找到最值元素 看是否为第一个假设元素
    不是就交换
    loop
posted @ 2024-11-05 12:30  GJ504b  阅读(75)  评论(0编辑  收藏  举报