標籤:
幾個常用的排序演算法:插入排序、快速排序、歸併排序
#include <stdio.h>#include <stdlib.h>#include <stdbool.h>/************************************************ * 插入排序法 * 第1次迴圈: 5, 3, 4, 6, 2, 1 -> 5, 5, 4, 6, 2, 1 -> 3, 5, 4, 6, 2, 1 * 第2次迴圈: 3, 5, 4, 6, 2, 1 -> 3, 5, 5, 6, 2, 1 -> 3, 4, 5, 6, 2, 1 * 第4次迴圈: 3, 4, 5, 6, 2, 1 -> 3, 3, 4, 5, 6, 1 -> 2, 3, 4, 5, 6, 1 * 第5次迴圈: 2, 3, 4, 5, 6, 1 -> 2, 2, 3, 4, 5, 6 -> 1, 2, 3, 4, 5, 6 ************************************************/void insert_sort(int *arr, int n){ int i = 0, j = 0, tmp = 0; for( i = 1; i < n; i++ ){ if( arr[i-1] > arr[i] ){ tmp = arr[i]; for( j = i - 1; arr[j] > tmp && j >= 0 ; j-- ){ arr[j+1] = arr[j]; } arr[j+1] = tmp; } /* printf("the %d times iteration : ",i); for( int j = 0 ; j < n; j++ ){ printf("%2d ",arr[j]); } printf("\n"); */ }}/************************************************ * 快速排序法 ************************************************/int partition(int *arr, int low, int high){ int tmp = arr[low]; while( low < high ){ while( low < high && arr[high]>= tmp ) high--; arr[low] = arr[high]; while( low < high && arr[low] <= tmp ) low++; arr[high] = arr[low]; } arr[low] = tmp; return low;}void q_sort(int *arr, int low, int high){ int pivot = 0; while( low < high ){ pivot = partition( arr,low,high ); // 對arr一分為二 q_sort( arr,low,pivot-1 ); // 低子表遞迴排序 low = pivot + 1; // 尾遞迴 }}/************************************************ * 2分歸併排序 ************************************************/void merge_sort( int *arr,int *tmp,int s_idx,int m_idx,int e_idx){ int i = s_idx, j = m_idx+1, k = s_idx; while( i != m_idx+1 && j != e_idx+1 ){ if( arr[i] < arr[j] ){ tmp[k++] = arr[i++]; } else{ tmp[k++] = arr[j++]; } } while( i != m_idx+1 ){ tmp[k++] = arr[i++]; } while( j != e_idx+1 ){ tmp[k++] = arr[j++]; } for( i = s_idx;i <= e_idx;i++ ){ arr[i] = tmp[i]; }}void m_sort(int *arr,int *tmp,int s_idx,int e_idx){ if( s_idx < e_idx ){ int mid = (s_idx + e_idx) / 2; // 將arr分為arr[0..mid]和arr[mid+1..n-1] m_sort( arr,tmp,s_idx,mid); // 遞迴將arr[0..mid]歸併為有序的tmp[0..mid] m_sort( arr,tmp,mid+1,e_idx); // 遞迴將arr[mid+1..n-1]歸併為有序的tmp[mid+1..n-1] merge_sort( arr,tmp,s_idx,mid,e_idx); // 將arr[0..mid]和arr[mid+1..n-1]歸併到tmp[0..n-1] }}/************************************************ * 反轉序列 ************************************************/void reverse(int *arr, int n){ int s_idx = 0, e_idx = n - 1; int tmp = 0; while( s_idx < e_idx ){ tmp = arr[s_idx]; arr[s_idx++] = arr[e_idx]; arr[e_idx--] = tmp; }}void show_arr(int *arr, int n){ for( int i = 0 ; i < n; i++ ){ printf("%2d ",arr[i]); } printf("\n");}/************************************************ * 二分尋找 * 數組 1 2 3 4 5 6 尋找 5 * | | | * low mid high * 迴圈1次: * 1 2 3 4 5 6 尋找 5 * | | | * low mid high ************************************************/bool binary_search(int *arr, int n, int key){ if( NULL == arr ) return false; int low = 0, high = n - 1, mid = 0; // low為數組首位,high為數組末位 while( low < high ){ mid = low + (( high - low ) >> 1); //防止溢出,移位也更高效。每次迴圈都要更新。 if( key < arr[mid] ){ // 若關鍵字小於中值 high = mid - 1; // 高下標調整到中下標小1 } else if( key > arr[mid] ){ // 若關鍵字大於中值 low = mid + 1; // 低下標調整到中下標加1 } else{ return true; } } return false;}int main(){ int i = 0; int arr[] = {5, 3, 4, 6, 2, 1, }; int len = sizeof(arr)/sizeof(arr[0]); int tmp[len]; m_sort(arr,tmp,0,len-1); printf("m_sort:\n"); show_arr(arr,len); reverse(arr,len); insert_sort(arr,len); printf("insert_sort:\n"); show_arr(arr,len); reverse(arr,len); q_sort(arr,0,len-1); printf("q_sort:\n"); show_arr(arr,len); int key = 5; printf("%d is%s in the arr\n",key,( binary_search(arr,len,key) ) ? "" : " not");}
輸出:
m_sort:
1 2 3 4 5 6
insert_sort:
1 2 3 4 5 6
q_sort:
1 2 3 4 5 6
5 is in the arr
C排序演算法