首先初始化了一個MAX大小的數組,用亂序函數將數組打亂,用於測試各個排序函數,先附上要測試的幾個基礎排序函數,後面附上亂序函數和主調度函數。代碼就那麼幾行,只是註釋的思亂佔了比較多的行數算法
冒泡排序編程
//冒泡排序 void bubbleSort(int *array, int size) { //循環1 從後向前逐個縮短比較範圍,由於後面是逐個成序的 for (int i = size - 1; i > 0; i--){ int flag = 1;//定義標誌變量,肯定當一次遍歷完成時候發生過交換 //循環2 逐個遍歷當前無序序列 for (int j = 0; j < i; j++){ //若是知足交換條件,則交換 if (array[j]>array[j + 1]){ swap(&array[j], &array[j + 1]); flag = 0;//因爲發生了交換,因此標誌變量置爲0 } } if (flag){//判斷標誌變量的值,若是此判斷能夠經過,則證實當遍歷玩整個無序部分都沒有發生一次交換, break;//證實整個序列都已經成序,直接跳出循環 } } }
選擇排序數組
//選擇排序 void selectSort(int *array, int size) { //循環1 用於控制遍歷最小值座標,每次首先覺得當前值最小,和後面全部元素開始比較 for (int i = 0; i < size-1; i++){ int index = i;//存儲當前最小值的索引, //這樣只在最後須要交換的時候發生一次交換,避免沒有必要的交換,加快程序執行 //循環2 用於控制遍歷後面沒有成序的部分和最小值比較 for (int j = i + 1; j < size; j++){ if (array[index]>array[j]){ index = j; } } //若是最小值的索引改變了,則交換 if (index != i){ swap(&array[index],&array[i]); } } }
插入排序函數
//插入排序 void insertSort(int *array, int size) { //因爲第0個元素就一個,因此是成序的,從第1個開始認爲是不成序的,和前面程序部分比較 //循環1 控制遍歷後面的不成序的序列 for (int i = 1; i < size; i++){ int temp = array[i];//記錄當前拿出來比較的值,它的位置可能被別人填充,因此記錄下來 int j = 0; //循環2 控制遍歷從目標數前一個向前遍歷成序序列,尋找目標數可插入的位置 for (j = i - 1; j >= 0 && array[j]>temp; j--){ array[j + 1] = array[j]; } if (j!= i - 1){//當j!=i-1說明上面循環的條件進入過,執行過,因此位置須要改變 array[j+1] = temp;//切記這裏是j+1,緣由是j的位置不知足條件退出,因此插入位置應該是j+1 } } }
二分插入排序測試
//二分插入排序,原理和插入排序相同,就是在找插入位置的時候使用了二分查找 void binaryInsertSort(int *array, int size) { for (int i = 1; i < size; i++){ int temp = array[i]; int left = 0; int right = i - 1; //二分查找部分,這樣比簡單的插入排序效率更高 while (left <= right){ int mid = (left + right) / 2; if (array[mid] < temp){ left = mid+1; } else{ right = mid - 1; } } int j = 0; for (j = i - 1; j >= left; j--){ array[j + 1] = array[j]; } if (j != i - 1){ array[j + 1] = temp; } } }
二分查找循環版code
//二分查找,循環版 void binarySearch(int *array, int des, int size) { int left = 0; int right = size - 1;//這裏的size是數組長度,要訪問最後一個元素,就樣長度減一 int mid = 0; //當left和right沒有錯過,則證實查找範圍合理,繼續查找 while (left <= right){ //每次開始循環,都要從新確認中間位置 mid = (left + right) / 2; //若是中間位置就是目標值,則找到了,跳出循環 if (array[mid] == des){ break; } //若是中間值大於目標,則在前半部分尋找,尋找上限編程mid-1 if (array[mid] > des){ right = mid - 1; } //反之,在後半部分尋找,尋找的下限變成mid+1 else{ left = mid + 1; } } //若是循環跳出的時候,還知足left<=right,則證實是由於找到了目標數,因此跳出,因此此時返回目標數索引 if (left <= right){ printf("\n查找成功,在數組的%d號位置\n",mid); } //反之,查找失敗 else{ printf("\n查找失敗\n"); } }
二分查找遞歸版排序
//遞歸版二分查找 int recursionBinarySearch(int *array, int left, int right, int des) { //判斷left和right沒有錯位,則查找繼續 if (left <= right){ //肯定中間位置 int mid = (left + right) / 2; //判斷中間位置是不是目標值,如果則返回 if (array[mid] == des){ return mid; } //若是中間值大於目標值,在前半部分繼續尋找 else if (array[mid] > des){ return recursionBinarySearch(array, left, mid - 1, des); } //若是中間位置小於目標值,在後半部分尋找 else if (array[mid] < des){ return recursionBinarySearch(array, mid + 1, right, des); } //若是這些狀況都不是,則是不合法的值,返回-1表示沒找到 else{ return -1; } } //若left和right已經錯過,則證實沒有找到 else{ return -1; } }
輔助的操做函數,包括 亂序函數,打印數組函數,交換元素值得函數遞歸
//交換函數 void swap(int *a, int *b) { int c = *a; *a = *b; *b = c; } //亂序算法,從後向前遍歷數組,讓目前位置數和小於它的任意索引位置交換,循環完成即完成簡單的亂序 void shuffle(int *array, int size) { srand((unsigned int)time(NULL)); int index = 0; for (int i = size-1; i >0; i--){ index=rand()%i; swap(&array[i],&array[index]); } } //數組打印函數 void printArray(int *array, int size) { for (int i = 0; i < size; i++){ printf("%d\t", array[i]); } }
主函數,負責測試各個排序函數索引
#include <stdio.h> #include <time.h> #include <stdlib.h> #define MAX 100 int main() { //定義並初始化數組 int array[MAX] = { 0 }; for (int i = 0; i < MAX; i++){ array[i] = i; } printf("亂序數組後\n"); shuffle(array, MAX); printArray(array, MAX); /*printf("\n冒泡排序後\n"); bubbleSort(array, MAX); printArray(array, MAX);*/ /*printf("\n選擇排序後\n"); selectSort(array, MAX); printArray(array, MAX);*/ /*printf("\n插入排序後\n"); insertSort(array, MAX); printArray(array, MAX);*/ printf("\n二分插入排序後\n"); binaryInsertSort(array, MAX); printArray(array, MAX); printf("\n二分查找 1 測試\n"); binarySearch(array, 1, MAX); printf("\n遞歸版二分查找 1 測試\n"); int index=recursionBinarySearch(array, 0, MAX - 1, 1); printf("\n查找成功,在數組的%d號位置\n", index); return 0; }