
排序1 排序
方法一:插入排序
O(N^2)
#includeusing namespace std; const int N = 100010; int n; int a[N]; int main() { cin >> n; for (int i = 0; i < n; i ++) cin >> a[i]; for (int i = 1; i < n; i ++) { int tmp = a[i]; int j; for (j = i; j > 0 && a[j - 1] > tmp; j --) a[j] = a[j - 1]; a[j] = tmp; } for (int i = 0; i < n - 1; i ++) printf("%d ", a[i]); cout << a[n - 1]; return 0; }
方法二:希尔排序
O(N^2)
#includeusing namespace std; const int N = 100010; int n; int a[N]; int main() { cin >> n; for (int i = 0; i < n; i ++) cin >> a[i]; for (int d = n / 2; d; d /= 2) for (int i = d; i < n; i ++) { int tmp = a[i]; int j; for (j = i; j >= d && a[j - d] > tmp; j -= d) a[j] = a[j - d]; a[j] = tmp; } for (int i = 0; i < n - 1; i ++) printf("%d ", a[i]); cout << a[n - 1]; return 0; }
方法三:堆排序
O(NlogN)
#includeusing namespace std; const int N = 100010; int n; int a[N]; // 将以root为根节点的堆调整成大根堆 void precdown(int root, int len) { int tmp = a[root]; int parent, child; for (parent = root; (parent * 2 + 1) < len; parent = child) { child = parent * 2 + 1; // 左儿子节点 if (child + 1 < len && a[child + 1] > a[child]) child ++; if (a[child] > tmp) a[parent] = a[child]; else break; } a[parent] = tmp; } int main() { cin >> n; for (int i = 0; i < n; i ++) cin >> a[i]; // 遍历所有根节点,建立大根堆 for (int i = n / 2 - 1; i >= 0; i --) precdown(i, n); // 每次将最大值与最后一个节点交换,然后维护一个长度 - 1的新大根堆 for (int i = n - 1; i; i --) { swap(a[0], a[i]); precdown(0, i); } for (int i = 0; i < n - 1; i ++) printf("%d ", a[i]); cout << a[n - 1]; return 0; }
方法四:归并排序
递归算法
O(NlogN)
#includeusing namespace std; const int N = 100010; int n; int a[N], tmp[N]; void merge_sort(int a[], int l, int r) { if (l >= r) return; int mid = l + r >> 1; merge_sort(a, l, mid), merge_sort(a, mid + 1, r); int i = l, j = mid + 1, k = l; while (i <= mid && j <= r) { if (a[i] > a[j]) tmp[k ++] = a[j ++]; else tmp[k ++] = a[i ++]; } while (i <= mid) tmp[k ++] = a[i ++]; while (j <= r) tmp[k ++] = a[j ++]; i = k = l; while (k <= r) a[i ++] = tmp[k ++]; } int main() { cin >> n; for (int i = 0; i < n; i ++) cin >> a[i]; merge_sort(a, 0, n - 1); for (int i = 0; i < n - 1; i ++) printf("%d ", a[i]); cout << a[n - 1]; return 0; }
非递归算法
#includeusing namespace std; const int N = 100010; int n; int a[N], tmp[N]; void merge(int a[], int tmp[], int l, int r, int r_end) { int l_end = r - 1; int i = l, j = r, k = l; while (i <= l_end && j <= r_end) { if (a[i] <= a[j]) tmp[k ++] = a[i ++]; else tmp[k ++] = a[j ++]; } while (i <= l_end) tmp[k ++] = a[i ++]; while (j <= r_end) tmp[k ++] = a[j ++]; i = k = l; while (i <= r_end) a[i ++] = tmp[k ++]; } void merge_pass(int a[], int tmp[], int len) { int i; for (i = 0; i <= n - 2 * len; i += 2 * len) merge(a, tmp, i, i + len, i + 2 * len - 1); if (i + len < n) merge(a, tmp, i, i + len, n - 1); else for (int j = i; j < n; j ++) tmp[j] = a[j]; } void merge_sort() { int len = 1; while (len < n) { merge_pass(a, tmp, len); len *= 2; } } int main() { cin >> n; for (int i = 0; i < n; i ++) cin >> a[i]; merge_sort(); for (int i = 0; i < n - 1; i ++) printf("%d ", a[i]); cout << a[n - 1]; return 0; }
排序2 Insert or Merge
分别用插入排序和归并排序,每一步操作后检查当前排序结果与所给序列是否一致。
#include#include using namespace std; const int N = 110; int n; int a[N], tmp[N], target[N]; bool merge_flag; bool match(int a[], int target[]) { for (int i = 0; i < n; i ++) if (a[i] != target[i]) return false; return true; } void print_out(int a[]) { for (int k = 0; k < n - 1; k ++) printf("%d ", a[k]); cout << a[n - 1]; } bool insert_sort(int a[], int target[]) { bool flag = false; for (int i = 1; i < n; i ++) { int t = a[i]; int j; for (j = i; j > 0 && a[j - 1] > t; j --) a[j] = a[j - 1]; a[j] = t; if (flag) { puts("Insertion Sort"); print_out(a); return true; } flag = match(a, target); } return false; } void merge(int a[], int tmp[], int l, int r, int r_end) { int l_end = r - 1; int i = l, j = r, k = l; while (i <= l_end && j <= r_end) { if (a[i] <= a[j]) tmp[k ++] = a[i ++]; else tmp[k ++] = a[j ++]; } while (i <= l_end) tmp[k ++] = a[i ++]; while (j <= r_end) tmp[k ++] = a[j ++]; i = k = l; while (i <= r_end) a[i ++] = tmp[k ++]; } void merge_pass(int a[], int tmp[], int len) { int i; for (i = 0; i <= n - 2 * len; i += 2 * len) merge(a, tmp, i, i + len, i + 2 * len - 1); if (i + len < n) merge(a, tmp, i, i + len, n - 1); else for (int j = i; j < n; j ++) tmp[j] = a[j]; } void merge_sort() { int len = 1; while (len < n) { merge_pass(a, tmp, len); len *= 2; if (match(a, target)) { merge_pass(a, tmp, len); puts("Merge Sort"); print_out(a); return; } } } int main() { cin >> n; for (int i = 0; i < n; i ++) cin >> a[i]; for (int i = 0; i < n; i ++) cin >> target[i]; memcpy(tmp, a, sizeof a); if (!insert_sort(a, target)) { memcpy(a, tmp, sizeof a); memset(tmp, 0, sizeof tmp); merge_sort(); } return 0; }