C語言排序 冒泡 選擇 快排

supermao12發表於2023-02-21

氣泡排序

氣泡排序是一種簡單的排序演演算法,其基本思想是重複地交換相鄰兩個元素,將較大的元素向右“冒泡”,較小的元素向左“沉澱”,從而將序列中的最大元素逐漸移到最後面。

#include <stdio.h>

void bub(int arr[],int n){   //首先定義空函式,第一個int引數接受列表,第二個為元素個數
    int i,j,temp;
    for(i=0;i<n-1;i++){     //這是進行幾輪比較。這裡是6輪。0,1,2,3,4,5 ,這裡有-1可以減少不必要的比較輪次,到最後自己就排好了,因為不是幾個數就比較就次,最後一個數會自己還原。
        for(j=0;j<n-i-1;j++){         //下標從0開始而不1所以需要n-1。你如果不-1,後面j++,arr[j+1]會超出範圍。-i是因為之後不需要再與最大數做比較了
        if(arr[j]>arr[j+1]) {
            temp = arr[j];
            arr[j] = arr[j + 1];
            arr[j + 1] = temp;
        }
        }
    }
}
int main(){
    int arr[] = {64,34,97,12,22,11,90};
    int n = sizeof(arr) / sizeof(arr[0]);
    bub(arr,n);
    printf("sort:\t");
    for(int i = 0; i < n; i++) {
        printf("%d\t",arr[i]);
    }
    return 0;
}

sort:   11      12      22      34      64      90      97

相較於其他排序演演算法,氣泡排序的優勢在於它的實現簡單、容易理解和編寫,適用於少量資料的排序。此外,氣泡排序在交換相鄰元素的過程中,可以記錄是否發生了交換,如果沒有發生交換則說明序列已經有序,可以提前結束排序,這樣可以減少排序的時間複雜度。但是,對於大量資料排序,氣泡排序的時間複雜度為O(n^2),效率較低,因此不適用於大規模資料的排序。

最佳化冒泡

#include <stdio.h>
#include <stdbool.h>    #有bool的時候最好加上

void bubble_sort(int arr[], int n) {
    bool is_sorted = false;
    int i, j, temp;

    for (i = 0; i < n - 1; i++) {
        is_sorted = true;
        for (j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {    //如果在這個for迴圈裡,此if一次都未執行。那麼is_sorted就不會變為false,也證明已經不需要換位置了。直接跳出當前迴圈,執行if語句,然後跳出大迴圈
                temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
                is_sorted = false;
            }
        }
        if (is_sorted) {
            break;
        }
    }
}

int main() {
    int arr[] = { 4, 2, 6, 1, 9, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int i;

    bubble_sort(arr, n);

    for (i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }

    return 0;
}

選擇排序

選擇排序是一種簡單直觀的排序演演算法,它的工作原理如下:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小(大)元素,然後放到已排序序列的末尾。以此類推,直到所有元素均排序完畢。

#include <stdio.h>

void selectsort(int arr[],int n){
    int min,i,j,temp;
    for(i=0; i < n- 1; i++){
        min=i;   //取得最小的下標
        for (j= i+1 ;j < n;j++)     //每次都要比較到最後一個元素所以j<n
            if(arr[j]<arr[min]){         //如果最小的下標的值不是最小值,將最小值的小標賦予min
                min=j;
            }
        temp=arr[i];               //將這個最小下標的值存起來
        arr[i]=arr[min];        //最小值賦予最小下標
        arr[min]=temp;            //將最小下標的值賦予min。也就是之前j的位置
    }
}

int main(){

    int a[] = {1,5,23,45,23,92,12};
    int n = sizeof(a)/sizeof(a[0]);
    selectsort(a,n);
    for (int i = 0;i<n;i++) {
        printf("%d\t", a[i]);
    }
    return 0;
}

快速排序

待排序的序列中,隨機選一個數字作為pivot中心軸
所有小於中心軸放左,大於則放右邊
左邊比pivot中心軸小,而右邊全比pivot大
然後對左子序列和右子序列重複以上的操作

/*
    快速排序演演算法
    思想: 遞迴思想
       什麼是遞迴?
       自我呼叫(迴圈)的函式
       有引數向著遞迴邊界靠,直到達到遞迴邊界
 */
/*
#include <stdio.h>
int f(int n){
    if(n==0||n==1){
        return 1;
    } else{
        return n*f(n-1);
    }
}
int main(){
    int n=5;
    printf("%d ",f(n));

    return 0;
}
 */
#include <stdio.h>
int FaindPos(int* a, int left, int right) {
    int val = a[left];
    while (left < right) {
        while (left < right && a[right] >= val) {
            right--;
        }
        a[left] = a[right];
        while (left < right && a[left] <= val) {
            left++;
        }
        a[right] = a[left];
    }
    a[left] = val;
    return left;
}

void QuickSort(int* a, int left, int right) {
    if (left >= right) {
        return;
    } else {
        int val = a[left];
        int pos = FaindPos(a, left, right);
        a[pos] = val;
        QuickSort(a, left, pos - 1);
        QuickSort(a, pos + 1, right);
    }
}

int main() {
    int a[] = {6, 5, 7, 8, 3, 4, 2, 1};
    QuickSort(a, 0, 7);
    for (int i = 0; i < 8; i++) {
        printf("%d ", a[i]);
    }
    return 0;
}

相關文章