# 簡單演算法 * [name=Ivy Lin] * [回首頁](https://hackmd.io/Qu2e9pQNSHC-e58Vp3ObhQ) ## 【簡介】 * **活用遞迴** 1. 通常快速排序的做法都包含一定程度的遞迴 2. 注意方法適用的範圍或數值 ## 【經典演算】 ### Binary Search :::info * **敘述** >在一個排序過後的數列中找尋某個指定的數。 >(補充)時間複雜度是O(log2N) ::: * **思路** >1. 切半討論=>大於往右找、小於往左找 >2. 停止=>當範圍超過時即停止搜尋 * **程式** ```clike= #include <stdio.h> int data[] = {1, 7, 9, 10, 27, 41, 60, 75, 89, 100}; void search(int s, int l, int r) { int mid = (l + r) / 2; if (l > r) printf("Not in the data\n"); if (data[mid] > s) search(s, mid + 1, r); if (data[mid] < s) search(s, l, mid - 1); if (data[mid] == s) printf("data[%d]=%d\n", mid, s); } int main() { int s; scanf("%d", &s); search(s, 0, 9) return 0; } ``` ### Merge Sort :::info * **敘述** >排序未被整理資料的一種方法 >(補充)時間複雜度是O(NlogN) ::: * **思路** >1. 屬於Divide and Conquer演算法,把問題先拆解(divide)成子問題, >逐一處理子問題後,將子問題的結果合併(conquer),如此便解決了原先的問題。 >2. 一樣利用"對半拆"的方式拆解資料 * **程式** **遞迴寫法** ```clike= #include <stdio.h> int input[100]; int left[55]; int right[55]; void paste(int l, int r, int m) { int n1 = m - l + 1; int n2 = r - m; for (int i = 0; i < n1; i++) left[i] = input[l + i]; for (int i = 0; i < n2; i++) right[i] = input[m + i + 1]; left[n1] = 2147483647; right[n2] = 2147483647; int i = 0, j = 0; for (int k = l; k <= r; k++) { if (left[i] <= right[j]) input[k] = left[i++]; else input[k] = right[j++]; } } void merge_cut(int l, int r) { if (l < r) { int m = (l + r) / 2; merge_cut(l, m); merge_cut(m + 1, r); paste(l, r, m); } } int main() { int n; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &input[i]); merge_cut(0, n); printf("(%d", input[0]); for (int i = 1; i < n; i++) printf(",%d", input[i]); printf(")\n"); return 0; } ``` **加入指標寫法** ```clike= #include <stdio.h> int left[55]; int right[55]; void paste(int *input, int l, int r, int m) { int n1 = m - l + 1; int n2 = r - m; for (int i = 0; i < n1; i++) left[i] = *(input + l + i); for (int i = 0; i < n2; i++) right[i] = *(input + m + i + 1); left[n1] = 2147483647; right[n2] = 2147483647; int i = 0, j = 0; for (int k = l; k <= r; k++) { if (left[i] <= right[j]) *(input + k) = left[i++]; else *(input + k) = right[j++]; } } void merge_cut(int *input, int l, int r) { if (l < r) { int m = (l + r) / 2; merge_cut(input, l, m); merge_cut(input, m + 1, r); paste(input, l, r, m); } } int main() { int n; int input[100]; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &input[i]); merge_cut(input, 0, n); printf("(%d", input[0]); for (int i = 1; i < n; i++) printf(",%d", input[i]); printf(")\n"); return 0; } ```