C語言學習:將數組元素進行冒泡排序


在實際開發中,有不少場景須要咱們將數組元素按照從大到小(或者從小到大)的順序排列,這樣在查閱數據時會更加直觀,例如:算法

一個保存了商品單價的數組,排序後更容易看出它們的性價比。編程

對數組元素進行排序的方法有不少種,好比冒泡排序、歸併排序、選擇排序、插入排序、快速排序等,其中最經典最須要掌握的是「冒泡排序」。數組

以從小到大排序爲例,冒泡排序的總體思想是這樣的:學習

從數組頭部開始,不斷比較相鄰的兩個元素的大小,讓較大的元素逐漸日後移動(交換兩個元素的值),直到數組的末尾。通過第一輪的比較,就能夠找到最大的元素,並將它移動到最後一個位置。優化

第一輪結束後,繼續第二輪。仍然從數組頭部開始比較,讓較大的元素逐漸日後移動,直到數組的倒數第二個元素爲止。通過第二輪的比較,就能夠找到次大的元素,並將它放到倒數第二個位置。spa

以此類推,進行 n-1(n 爲數組長度)輪「冒泡」後,就能夠將全部的元素都排列好。視頻

整個排序過程就好像氣泡不斷從水裏冒出來,最大的先出來,次大的第二齣來,最小的最後出來,因此將這種排序方式稱爲冒泡排序(Bubble Sort)。blog

下面咱們以「3  2  4  1」爲例對冒泡排序進行說明。排序

第一輪  排序過程教程

3  2  4  1    (最初)

2  3  4  1    (比較3和2,交換)

2  3  4  1    (比較3和4,不交換)

2  3  1  4    (比較4和1,交換)

第一輪結束,最大的數字 4 已經在最後面,所以第二輪排序只須要對前面三個數進行比較。

第二輪  排序過程

2  3  1  4 (第一輪排序結果)

2  3  1  4 (比較2和3,不交換)

2  1  3  4 (比較3和1,交換)

第二輪結束,次大的數字 3 已經排在倒數第二個位置,因此第三輪只須要比較前兩個元素。

第三輪  排序過程

2  1  3  4  (第二輪排序結果)

1  2  3  4  (比較2和1,交換)

至此,排序結束。

算法總結及實現

對擁有 n 個元素的數組 R[n] 進行 n-1 輪比較。

第一輪,逐個比較 (R[1], R[2]),  (R[2], R[3]),  (R[3], R[4]),  …….  (R[N-1], R[N]),最大的元素被移動到 R[n] 上。

第二輪,逐個比較 (R[1], R[2]),  (R[2], R[3]),  (R[3], R[4]),  …….  (R[N-2], R[N-1]),次大的元素被移動到 R[n-1] 上。

。。。。。。

以此類推,直到整個數組從小到大排序。

具體的代碼實現以下所示:

#include <stdio.h>

int main(){

  int nums[10] = {4, 5, 2, 10, 7, 1, 8, 3, 6, 9};

  int i, j, temp;

  //冒泡排序算法:進行 n-1 輪比較

  for(i=0; i<10-1; i++){

    //每一輪比較前 n-1-i 個,也就是說,已經排序好的最後 i 個不用比較

    for(j=0; j<10-1-i; j++){

      if(nums[j] > nums[j+1]){

        temp = nums[j];

        nums[j] = nums[j+1];

        nums[j+1] = temp;

      }

    }

  }

 

  //輸出排序後的數組

  for(i=0; i<10; i++){

    printf("%d ", nums[i]);

  }

  printf("\n");

 

  return 0;

}

運行結果:

1 2 3 4 5 6 7 8 9 10

優化算法

上面的算法是大部分教材中提供的算法,其中有一點是能夠優化的:當比較到第 i 輪的時候,若是剩下的元素已經排序好了,那麼就不用再繼續比較了,跳出循環便可,這樣就減小了比較的次數,提升了執行效率。

未經優化的算法必定會進行 n-1 輪比較,通過優化的算法最多進行 n-1 輪比較,高下立判。

優化後的算法實現以下所示:

#include <stdio.h>

int main(){

  int nums[10] = {4, 5, 2, 10, 7, 1, 8, 3, 6, 9};

  int i, j, temp, isSorted;

 

  //優化算法:最多進行 n-1 輪比較

  for(i=0; i<10-1; i++){

    isSorted = 1; //假設剩下的元素已經排序好了

    for(j=0; j<10-1-i; j++){

      if(nums[j] > nums[j+1]){

        temp = nums[j];

        nums[j] = nums[j+1];

        nums[j+1] = temp;

        isSorted = 0; //一旦須要交換數組元素,就說明剩下的元素沒有排序好

      }

    }

    if(isSorted) break; //若是沒有發生交換,說明剩下的元素已經排序好了

  }

  for(i=0; i<10; i++){

    printf("%d ", nums[i]);

  }

  printf("\n");

 

  return 0;

}

咱們額外設置了一個變量 isSorted,用它做爲標誌,值爲「真」表示剩下的元素已經排序好了,值爲「假」表示剩下的元素還未排序好。

每一輪比較以前,咱們預先假設剩下的元素已經排序好了,並將 isSorted 設置爲「真」,一旦在比較過程當中須要交換元素,就說明假設是錯的,剩下的元素沒有排序好,因而將 isSorted 的值更改成「假」。

每一輪循環結束後,經過檢測 isSorted 的值就知道剩下的元素是否排序好。

 

另外若是你想更好的提高你的編程能力,學好C語言C++編程!彎道超車,快人一步!筆者這裏或許能夠幫到你~

分享(源碼、項目實戰視頻、項目筆記,基礎入門教程)

歡迎轉行和學習編程的夥伴,利用更多的資料學習成長比本身琢磨更快哦!

編程學習書籍:


編程學習資料:

相關文章
相關標籤/搜索