氣泡排序與選擇排序
氣泡排序
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