排序演算法-C語言
阿新 • • 發佈:2020-12-24
// 排序演算法 //排序演算法測試流程 //指定數列 c //隨機生成多少個從多少到多少的數 //輸出排序前的數,輸出排序後的數 #include <stdio.h> #include <stdlib.h> #include <time.h> #define BOOL int #define TRUE 1 #define FALSE 0 #define sort bubble_sort // 使用哪種排序 // 隨機數模式元件 const BOOL ran = TRUE; // 隨機模式 開關 const int SIZE_ran = 100; // 長度 const int RANGE_ran = 100; // 範圍 // 自定義模式 const int SIZE_C = 8; int c[SIZE_C] = {6,5,3,8,1,2,7,4}; const BOOL RESULT_DISPLAY = TRUE; const BOOL LITTLE = FALSE; // 小步驟後公屏 的開關 const BOOL BIG = FALSE; // 大步驟後公屏 的開關 const BOOL STEP = FALSE; // 顯示步驟 const BOOL TIME = TRUE; // 顯示演算法時間的開關 const BOOL CHECK = TRUE; // 檢查數列是否正序 int partition(int arr[],int low, int high); // 排序函式 一萬個 void insertion_sort(int arr[],int size); // 插入排序 0.219763 0.200803 void half_insertion_sort(int arr[],int size); // 折半插入排序 0.078195 0.079068 void shell_sort(int arr[], int size); // 希爾排序 0.002527 0.002765 void bubble_sort(int arr[], int size); // 氣泡排序 0.277525 0.291703 void quick_sort(int arr[], int size); // 快速排序 pivot 0.001275 void select_sort(int arr[], int size); // 選擇排序 0.119310 void heap_sort(int arr[], int size); // 堆排序 0.001395 0.001515 void merge_sort(int arr[], int size); // 歸併排序 0.001811 0.002150 // 外圍函式 int display_arr(int arr[],int size); //列印陣列的函式 int* make_ran_arr(int size,int range); //產生 長度為size的 範圍是0~range-1的 隨機數 void display_process(BOOL ok,int arr[],int size); //列印排序過程 int partiton(int arr[],int low, int high); //快速排序的分段法 void quick_sort_inside(int arr[], int start, int end); //快速排序的內部核心 void check(int arr[], int size); // 檢查陣列是否符合順序 void build_max_heap(int arr[], int size); // 建立大根堆 void head_adjust(int add[], int k, int size); // 調整堆 void merge_sort_inside(int arr[], int low,int high);// 歸併排序內建函式 void merge(int arr[], int low,int mid,int high); //歸併排序合併兩個函式 /*----------------------- 主函式 -----------------------*/ int main(void){ int *a = c; int SIZE_a = SIZE_C; if (ran == TRUE){ a = make_ran_arr( SIZE_ran, RANGE_ran); SIZE_a = SIZE_ran; } printf("Before sort: "); // display_arr(a, SIZE_a); sort(a, SIZE_a); if (RESULT_DISPLAY == TRUE){ printf("After sort : "); display_arr(a, SIZE_a); } if (CHECK == TRUE) check(a,SIZE_a); return 0; } /*section---------------------------外圍函式-------------------------------------*/ // 列印陣列 int display_arr(int arr[],int size){ int count = 0; for (count = 0; count < size - 1; count++){ printf("%d,",arr[count]); } printf("%d.\n",arr[size-1]); return 0; } // 隨機數陣列生成 int* make_ran_arr(int size,int range){ int* array = (int *)malloc(sizeof(int) * size); int count = 0; for (count = 0; count < size; count ++){ array[count] = rand() % range; } return array; } void display_process(BOOL ok,int arr[],int size){ if (ok == TRUE){ printf("after one : "); display_arr(arr,size); } } int partition(int arr[],int low, int high){ int pivot = arr[low]; while (low <high){ while(low <high && arr[high] >=pivot) high--; arr[low] = arr[high]; while(low <high && arr[low] <= pivot) low++; arr[high] = arr[low]; } arr[low] = pivot; return low; } void quick_sort_inside(int arr[], int start, int end){ int pivot = partition(arr,start,end); if (start < pivot-1) quick_sort_inside(arr, start, pivot-1); if (end > pivot+1) quick_sort_inside(arr, pivot+1, end); } void check(int arr[], int size){ BOOL ok = TRUE; int i; for (i=0; i <size-1;i++){ if (arr[i]>arr[i+1]){ ok = FALSE; break; } } if (ok ==TRUE) printf("本次排序成功!\n"); else printf("本次排序失敗!\n"); } void build_max_heap(int *arr, int size){ for (int i= size/2; i>0; i--){ head_adjust(arr, i, size); } } void head_adjust(int arr[], int k, int size_adjust){ arr[0] = arr[k]; int i; for (i=2*k ; i <= size_adjust ; i*=2){ if (i+1<= size_adjust && arr[i] <arr[i+1]) i +=1; if (arr[0]>= arr[i]) break; else{ arr[k] = arr[i]; k = i; } } arr[k] = arr[0]; } void merge_sort_inside(int arr[], int low,int high){ if (low<high){ int mid = (low+high)/2; merge_sort_inside(arr, low, mid); merge_sort_inside(arr, mid+1, high); merge(arr,low,mid,high); } } void merge(int arr[], int low,int mid,int high){ int i,j,k; int fuzhu[high-low+1]; for (k = 0; k <= high-low;k++) // 填充輔助陣列 fuzhu[k] = arr[k+low]; for (i = low, j = mid+1, k = i; i<=mid&& j<=high; k++){ if (fuzhu[i-low] <fuzhu[j-low]){ arr[k] = fuzhu[i-low]; i++; } else{ arr[k] = fuzhu[j-low]; j++; } } while (i <= mid){ arr[k] = fuzhu[i-low]; k++; i++; } while (j <= high){ arr[k] = fuzhu[j-low]; k++; j++; } } /*section---------------------------排序---------------------------------------*/ // 需要提供計時功能 // 需要提供大、小步驟輸出函式的功能 //{ // clock_t start_t,finish_t; // start_t = clock(); // finish_t = clock(); // if (TIME == TRUE) printf("本次排序用時:%f 秒\n",(double)(finish_t-start_t)/CLOCKS_PER_SEC); //} // 插入排序 void insertion_sort(int arr[],int size){ clock_t start_t,finish_t; start_t = clock(); int count = 0, key = 0; for(count = 1; count <size; count++){ if (STEP == TRUE) printf("前%d個已經排好\n",count); if (count != 1){ display_process(BIG, arr, size); } int i = count - 1; for(i = count - 1; i >=0; i--){ if (arr[i+1] < arr[i]){ key = arr[i+1]; arr[i+1] = arr[i]; arr[i] = key; display_process(LITTLE, arr, size); } else{ break; } } } finish_t = clock(); if (TIME == TRUE) printf("本次排序用時:%f 秒\n",(double)(finish_t-start_t)/CLOCKS_PER_SEC); } // 折半插入 void half_insertion_sort(int arr[],int size){ clock_t start_t,finish_t; start_t = clock(); int i,j,low,high,mid,key; for (i=1; i < size; i++){ if (STEP == TRUE) printf("前%d個已經排好\n",i); key = arr[i]; low = 0; high = i-1; mid = (low +high)/2; while (low <= high){ if (arr[mid] <= key){ low = mid+1; mid = (low +high)/2; }else{ high = mid-1; mid = (low +high)/2; } } for (j = i-1; j >= high+1; j--){ arr[j+1] = arr[j]; } arr[high+1] = key; if (i != size-1) display_process(BIG, arr, size); } finish_t = clock(); if (TIME == TRUE) printf("本次排序用時:%f 秒\n",(double)(finish_t-start_t)/CLOCKS_PER_SEC); } // 希爾排序,內部呼叫折半插入 void shell_sort(int arr[],int size){ clock_t start_t,finish_t; start_t = clock(); int duanshu,i,j,key; for (duanshu = size/2; duanshu>=1; duanshu = duanshu/2 ){ for (i = duanshu; i < size; i++){ if (arr[i] < arr[i-duanshu]){ key = arr[i]; for (j = i-duanshu; j >= 0 && key <arr[j]; j = j-duanshu){ arr[j + duanshu] = arr[j]; } arr[j+duanshu] = key; display_process(LITTLE, arr, size); } } display_process(BIG, arr, size); if (STEP == TRUE) printf("已經完成段長/組數量 為 %d 的排序\n",duanshu); } finish_t = clock(); if (TIME == TRUE) printf("本次排序用時:%f 秒\n",(double)(finish_t-start_t)/CLOCKS_PER_SEC); } // 氣泡排序 void bubble_sort(int arr[], int size){ clock_t start_t,finish_t; start_t = clock(); int i,j,key; for (i = 0; i < size ; i++){ for (j = size-1; j>i; j--){ if ( arr[j] < arr[j-1]){ key = arr[j]; arr[j] = arr[j-1]; arr[j-1] =key; } } if (STEP == TRUE) printf("前%d個已經排完了\n",i+1); display_process(BIG, arr, size); } finish_t = clock(); if (TIME == TRUE) printf("本次排序用時:%f 秒\n",(double)(finish_t-start_t)/CLOCKS_PER_SEC); } void quick_sort(int arr[], int size){ clock_t start_t,finish_t; start_t = clock(); quick_sort_inside(arr, 0, size-1); finish_t = clock(); if (TIME == TRUE) printf("本次排序用時:%f 秒\n",(double)(finish_t-start_t)/CLOCKS_PER_SEC); } void select_sort(int arr[], int size){ clock_t start_t,finish_t; start_t = clock(); int i,j,min,key; for (i = 0; i < size-1; i++){ min = i; for (j = i+1; j < size; j++) if (arr[j] < arr[min]) min = j; key = arr[min]; arr[min] = arr[i]; arr[i] = key; } finish_t = clock(); if (TIME == TRUE) printf("本次排序用時:%f 秒\n",(double)(finish_t-start_t)/CLOCKS_PER_SEC); } void heap_sort(int arr[], int size){ clock_t start_t,finish_t; start_t = clock(); int new[size+1],i; for (i = 1; i<= size; i++) new[i] = arr[i-1]; build_max_heap( new,size); for (i = 1; i<size; i ++){ new[0] = new[1]; new[1] = new[size - i+1]; new[size - i+1] = new[0]; head_adjust(new, 1, size-i); } for (i =0; i <=size; i++) arr[i] = new[i+1]; finish_t = clock(); if (TIME == TRUE) printf("本次排序用時:%f 秒\n",(double)(finish_t-start_t)/CLOCKS_PER_SEC); } void merge_sort(int arr[], int size){ clock_t start_t,finish_t; start_t = clock(); merge_sort_inside(arr, 0, size-1); finish_t = clock(); if (TIME == TRUE) printf("本次排序用時:%f 秒\n",(double)(finish_t-start_t)/CLOCKS_PER_SEC); }