標籤:mat element 快速排序 log 簡單的 插入 由來 需要 順序
冒泡排序(英語:Bubble Sort)是一種簡單的排序演算法。它重複地走訪過要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重複地進行直到沒有再需要交換,也就是說該數列已經排序完成。這個演算法的名字由來是因為越小的元素會經由交換慢慢“浮”到數列的頂端。
時間複雜度O(n2)
void bubble_sort(int *array,int len){ int i = 0 ; int j = 0 ; int temp = 0; for(i = len; i > 0;i--) { for(j = 1;j < i;j++) { if(array[j-1] > array[j]) { temp = array[j]; array[j] = array[j-1]; array[j-1] = temp; } } }}
插入排序(英語:Insertion Sort)是一種簡單直觀的排序演算法。它的工作原理是通過構建有序序列,對於未排序資料,在已排序序列中從後向前掃描,找到相應位置並插入。
時間複雜度O(n2)
/* * 從第一個元素開始,該元素可以認為已經被排序 * 取出下一個元素,在已經排序的元素序列中從後向前掃描 * 如果該元素(已排序)大於新元素,將該元素移到下一位置 * 重複步驟3,直到找到已排序的元素小於或者等於新元素的位置 * 將新元素插入到該位置後 * 最優的時間O(n) * 最壞的時間O(n2) * 平均的時間O(n2) */void insert_sort(int *array,int len){ int i = 0 ; int j = 0 ; int temp = 0; for(i = 1; i < len;i++) { temp = array[i]; for(j = i;j > 0 && array[j-1] > temp;j--) array[j] = array[j-1]; array[j] = temp; }}
歸併排序
時間複雜度O(n * log2(n))
/* 分解:將n個元素分成各含n/2個元素的子序列 * 解決:用合并排序法對兩個子序列遞迴地排序 * 合并:合并兩個已排序的子序列以得到排序結果 * 時間複雜度O(n*log2(n)) */voidmerge_sort_recursive(int arr[], int reg[], int left, int right) { if (left >= right) return; int len = right - left, mid = (len >> 1) + left; int left1 = left, right1 = mid; int left2 = mid + 1, right2 = right; merge_sort_recursive(arr, reg, left1, right1); merge_sort_recursive(arr, reg, left2, right2); int k = left; while (left1 <= right1 && left2 <= right2) reg[k++] = arr[left1] < arr[left2] ? arr[left1++] : arr[left2++]; while (left1 <= right1) reg[k++] = arr[left1++]; while (left2 <= right2) reg[k++] = arr[left2++]; for (k = left; k <= right; k++) arr[k] = reg[k];}void merge_sort(int arr[], const int len) { int reg[len]; merge_sort_recursive(arr, reg, 0, len - 1); }
二元堆積排序
static void swap(int *a,int *b) { int index = *a; *a = *b; *b = index;}/* *假設"第一個元素"在數組中的索引為 0 的話,則父節點和子節點的位置關係如下: *(01) 索引為i的左孩子的索引是 (2*i+1); *(02) 索引為i的左孩子的索引是 (2*i+2); *(03) 索引為i的父結點的索引是 floor((i-1)/2); *//*自上而下*/void max_heapify(int array[], int start, int end) { printf("start is %d\n",start); int parent = start; int child = parent * 2 + 1;//左孩子 while(child <= end) { if(child + 1 <= end && array[child] < array[child+1]) child++; if(array[parent] > array[child]) return; else{ swap(&array[parent],&array[child]); parent = child; child = (parent << 1) + 1; } }}void heap_sort(int array[],int len){ /* 初始化,i從最後一個根節點節點開始調整,自下而上,a[0]是根節點*/ for(int i = len/2-1;i >= 0; i--) max_heapify(array,i,len-1); for(int i = len -1;i >= 0;i--) { //將第一個元素和已經排好元素前一位做交換,再重新排序 swap(&array[0],&array[i]); max_heapify(array, 0, i - 1); }}
快速排序
static void swap(int *a,int *b){ int index = *a; *a = *b; *b = index;}static int median3(int *array,int left,int right){ int center = (left + right) >> 1; if(array[left] > array[center]) swap(&array[left],&array[center]); if(array[left] > array[right]) swap(&array[left],&array[right]); if(array[center] > array[right]) swap(&array[center],&array[right]); /* array[left] < array[center] < array[right]*/ return array[center];}static void quick_array(int *array,int left,int right){ int i; int j; int privot; int center; if((right-left) >= 2) { privot = median3(array,left,right); center = (left + right) >> 1; printf("left center right ---> %d %d %d\n",array[left],array[center],array[right]); swap(&array[center],&array[right-1]); for(int i = 0;i < 10 ; i++) printf("array[%d] = %d ",i,array[i]); printf("\n"); i = left; j = right - 1; for(;;) { while(array[++i] < privot); while(array[--j] > privot); if(i < j) swap(&array[i],&array[j]); else break; } swap(&array[i],&array[right-1]); quick_array(array,left,i-1); quick_array(array,i+1,right); }else{ if((right-left) == 0) return; else if((right-left) == 1) { if(array[left] > array[right]) swap(&array[left],&array[right]); } }}void quick_sort(int *array,int len){ quick_array(array,0,len-1);}
常見的排序演算法