經常使用排序

1.桶排序

四次循環分別循環了m,n,m,n次,因此時間複雜度爲O(2*(m+n));數組

特色:時間複雜度小,可是很是浪費空間,尤爲不適用用小數。ui

void ascending(){
    int a[11],i,j,t;
    
    for (i = 0; i <= 10; i++) {
        a[i] = 0; //將10個桶都清空
    }
    
    for (i = 0; i < 5; i++) {
        printf("輸入第%d個小數:",i);
        scanf("%d",&t);
        a[t]++; ////每輸入數字,就在數字所在的桶插一個旗子
    }
    
    for (i = 0; i <= 10; i++) {//從左到後數
        for (j = 1; j <= a[i]; j++) {//遍歷桶的旗子
            printf("%d",i);
        }
    }
    
}

void descending(){
    
    int arr[1001],i,j,t,n;
    
    for (i = 0; i <= 1000; i++) {
        arr[i] = 0;
    }
    printf("須要排序多少位數字:");
    scanf("%d",&n);
    for (i = 1; i <= n; i++) {
        printf("輸入第%d個小數:",i);
        scanf("%d",&t);
        arr[t]++;
    }
    
    for (i = 1000; i >= 0; i--) {//從右到左數

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

2.冒泡排序

特色:節省空間,可是雙重排序時間複雜度也就是O(N平方),很是高。spa

void sorting(){

    int arr[100],i,j,t,n;
    printf("須要排序多少位數字:");
    scanf("%d",&n);
    
    //循環讀入n個數到數組中
    for (i = 1; i <= n; i++) {
        printf("輸入第%d位數字:",i);
        scanf("%d",&arr[i]);
    }
    
    //冒泡排序的核心部分
    for (i = 1; i <= n-1; i++) {//n個數排序,只需進行n-1排序,最後一個數字確定是最小的
        for (j = 1; j <= n-1; j++) {//和剩下的n-1個數字進行比較
            if (arr[j] > arr[j+1]) {//交換位置,升序降序在這裏控制
                t = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = t;
            }
        }
    }
    
    for (i = 1; i <= n; i++) {
         printf("%d \n",arr[i]);
        
    }
    
}




//使用結構體,字典排序
struct student{
    char name[21];
    int score;
};

void dicSorting(){
    
    struct student arr[100],t;
    int i,j,n;
    printf("須要排序多少位學生:");
    scanf("%d",&n);
    
    for (i = 1; i <= n; i++) {
        printf("輸入第%d位學生信息:",i);
        scanf("%s %d",arr[i].name,&arr[i].score);//name自己是數組類型,數組類型都是以指針形式傳入數組的,因此不須要&
    }
    
    //冒泡排序的核心部分
    for (i = 1; i <= n-1; i++) {
        for (j = 1; j <= n-1; j++) {
            if (arr[j].score > arr[j+1].score) {
                t = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = t;
            }
        }
    }
    
    for (i = 1; i <= n; i++) {
        printf("%s \n",arr[i].name);
        
    }
    
    
}

3.選擇排序

特色:和冒泡選擇的查找過程是同樣的,可是交換過程不同。冒泡選擇是相鄰大於就交互,而選擇排序是先記錄位置,但排序結束才後交換。時間複雜度稍低於冒泡排序。注意選擇排序是不穩定的,舉例序列5 8 5 2 9, 咱們知道第一遍選擇第1個元素5會和2交換,那麼原序列中2個5的相對先後順序就被破壞了,序列做爲vlaue是不影響,若是爲key,那麼它們的value就會順序就會變化了(前面key5的value排在後面key爲5的後面了)。指針

int min;
    //選擇排序的核心部分
    for (i = 1; i <= n-1; i++) {
        min = i;//假定arr[i]是最大的數字
        for (j = i+1; j <= n-1; j++) {
            if (arr[j] > arr[min]) {
                min = j;//若是大於,記錄j的位置
            }
        }
        if (min != i) {//若是min的位置不位於首位,即i與數字最大的即m位置互換
            t = arr[i];
            arr[i] = arr[min];
            arr[min] = t;
        }
    }

4.快速排序

特色:既解決了桶排序的空間佔用,又解決了冒泡的長時間。時間複雜度 最理想 O(nlogn) 最差時間O(n^2)code

int a[101],n;


void quickSort(int left,int right){
    
    int i,j,t,temp;
    if (left > right) {//當只剩下2個數字比較的時候,就中止
        return;
    }
    
    temp = a[left];//以最左邊的數爲基準數
    i = left;
    j = right;
    while (i != j) {//確保不會相遇。
        while (a[j] >= temp && i<j) {//先從右往左找,比基準數小位置
            j--;
        }
        while (a[i] <= temp && i<j) {//再從左往右找,比基準數大位置
            i++;
        }
        //交換數組中這兩個位置
        if (i < j) {//若是i和j沒有相遇的話
            t = a[i];
            a[i] = a[j];
            a[j] = t;
            
        }
        printf("i:%d,j:%d",i,j);
    }
    
    //此時i == j,二者相遇,將基準數歸位到最左邊
    a[left] = a[i];
    a[i] = temp;
    
    //繼續處理,左右兩邊
    quickSort(left, i-1);
    quickSort(i+1, right);
    
}



int main(int argc, const char * argv[]) {
    // insert code here...
    
    int i;
    printf("須要排序多少位數字:");
    scanf("%d",&n);
    
    for (i = 1; i <= n; i++) {
        printf("輸入第%d位數字:",i);
        scanf("%d",&a[i]);
    }
    
    quickSort(1, n);
    
    for (i = 1; i <= n; i++) {
        printf("%d \n",a[i]);
    }
    
    
    return 0;
}
相關文章
相關標籤/搜索