氣泡排序與選擇排序超詳細講解

GJ504b發表於2024-11-05

氣泡排序與選擇排序

氣泡排序

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

相關文章