1.選擇排序
選擇排序法(Selection Sort) 是對數組進行排序常用的一種簡單直觀的方法。
該方法通過多次循環,每次從待排序的元素中選出最小(或最大)的一個元素,存放在數組的起始位置,然后再從剩余的未排序元素中尋找到最小(大)元素,然后放到已排序的序列的末尾。從而實現將一個數組內的所有元素按大小升序或降序排序
如圖所示:
話不多說,先上例題:
假設有一組待排序的數組a
該數組包含這些元素:2, 45, 6, 12, 87, 34, 103, 53, 25
現對其使用選擇排序法進行升序排序
代碼分析:
首先定義數組以及數組長度變量len
通過for循環
讓循環控制變量i從數組的最后一項(len-1)開始
使用自定義的max函數返回數組a從0到第i項中最大值的下標。
得到最大值下標后,把該最大值放到此時數組的末尾,也就是第len-1項
下一次循環,i變成len-2,再得到從0到第i項中最大值的下標,再次將其放到第i項,也就是數組的倒數第二項。
依次循環下去,直到i等於1,循環結束
排序完成,最后遍歷輸出。
代碼:
#include <stdio.h> int max(int a[], int n); int main() { int a[] = { 2, 45, 6, 12, 87, 34, 103, 53, 25 }; int len = sizeof(a) / sizeof(int); // 選擇排序 for (int i = len - 1; i > 0; i--) { int maxid = max(a, i + 1); int t = a[maxid]; a[maxid] = a[i]; a[i] = t; } // 遍歷輸出 for (int i = 0; i < len; i++) printf("%d ", a[i]); printf("\n\n\n"); return 0; } int max(int a[], int n) // 返回數組a中最大值的下標; n表示該數組的長度 { int max = 0; for (int i = 0; i < n; i++) { if (a[i] > a[max]) max = i; } return max; }
運行結果:
程序運行成功。
2.冒泡排序
冒泡排序(Bubble Sort)也是對數組進行排序常用的方法,它通過多次循環,每次都從頭到尾比較相鄰兩項的大小並進行位置調換來完成排序,也就是說,它要重復地遍歷整個數組, 直到數組的每個元素都排序完畢。
如圖所示:
同樣還是上面的例題:
假設有一組待排序的數組a
該數組包含這些元素:2, 45, 6, 12, 87, 34, 103, 53, 25
現對其使用冒泡排序進行升序排序
代碼分析:
先定義數組和數組的長度變量len,數組長度可以通過 (整個數組所占字節大小)/(單個元素所占字節大小) 來得到;
接着進入排序,使用兩層嵌套循環,第一層的控制變量i表示遍歷數組的次數,完成整個冒泡排序過程需要[數組長度-1]次,所以我們讓它從1開始直至len-1;
第二層的控制變量 j 表示遍歷到數組的第幾個元素,j 從0開始直至len-2,比如當 j = 0時,比較第0項和第1項的大小,若后一項小於前一項,則交換它們的位置;
上述嵌套循環完成后,數組也就完成了排序。
代碼:
#include <stdio.h> int main() { int a[] = { 2, 45, 6, 12, 87, 34, 103, 53, 25 }; int len = sizeof(a) / sizeof(int); // 冒泡排序 for (int i = 1; i < len; i++) { for (int j = 0; j < len-1; j++) { if (a[j + 1] < a[j]) { int t = a[j + 1]; a[j + 1] = a[j]; a[j] = t; } } } // 遍歷輸出 for (int i = 0; i < len; i++) printf("%d ", a[i]); printf("\n\n\n"); return 0; }
運行結果與選擇排序法相同。
3.二分查找
問題引入:
現有上述按升序排序完的數組: 2, 6, 12, 25, 34, 45, 53, 87, 103;
要求定義一個函數,該函數可以返回某個指定整數(假設為34)在該數組中的下標。
代碼分析:
定義三個記號left(左)、mid(中)、right(右),初始位置左記號在數組第0項,右記號在最后一項;
使用while循環,每次循環比較中記號所表示項與指定整數的大小關系,以判斷是否進一步縮小范圍或返回結果;
若范圍縮小到左記號跑到右記號的右邊還沒找到指定整數,則結束循環,返回-1.
代碼:
int search(int a[], int n, int x) // 傳入參數:待查找數組a,數組長度n,查找指定整數x { int index = -1; // 返回值初始化為-1,若未找到指定整數則返回-1 // 二分查找法 int left, right, mid; // 定義左中右三個下標記號 left = 0; // 左記號初始位置為第0項 right = n - 1; // 右記號初始位置為最后一項 while (left < right) { // 當左記號不在右記號的左邊時,查找過程結束,未找到指定整數,結束循環 mid = (left + right) / 2; if (a[mid] == x) { // 找到指定整數,將該下標傳遞給返回值index,並結束循環 index = mid; break; } else if (a[mid] < x) { // 若中記號所表示的項 小於 指定整數,則表明此時數組左半部分的所有項均小於指定整數 left = mid + 1; // 這時將左記號移至此時中記號的右一位,也就是將查找范圍縮小到此時數組的右半部分 } else { // 反之則移動右記號,將范圍縮小到左半部分 right = mid - 1; } } return index; }
運行結果:
在主函數中成功正確輸出指定整數下標:4
總結:
二分查找法相較於一般的遍歷查找法 循環次數更少,程序運行效率更高,不過待查找的數組一定得是有序的數組才可使用該方法。
END:)
注:1 2算法示意動圖引用自菜鳥教程