1、快速排序
快速排序基于的是分治的思想,然后写一个二叉树先序访问的递归。
首先确定分界点,mid = l + r >> 1。
重点是:如何优雅地递归左右两端。
void quick_sort(int q[], int l, int r) { //递归的终止条件 if(l >= r) return; //分解成子问题 int mid = l + r >> 1, i = l - 1, j = r - 1; while(i < j) { do i++; while(q[i] < x); do j--; while(q[j] > x); if(i < j) swap(q[i], q[j]); } //递归处理子问题 quick_sort(q, l, mid), quick_sort(q, mid + 1, r); //子问题合并,由于我们使用了优雅的实现左右两端的算法,一直是在一个数组里进行操作,所以不需要合并 }
2、归并排序
归并排序同样是基于分治的思想,他同样是三部分。
确定分界点mid = l + r >> 1
分解成子问题
合并子问题
void merge_sort(int q[], int l, int r) { //递归终止条件 if(l >= r) return; //分解成子问题 int mid = l + r >> 1; //递归处理子问题 merge_sort(q, l ,mid),merge_sort(q, mid + 1, r); //合并子问题 int k = 0, i = l, j = mid + 1; while(i <= mid && j <= r) { if(q[i] <= q[j]) tmp[k++] = q[i++]; else tmp[k++] = q[j++]; } while(i <= mid) tmp[k++] = q[i++]; while(j <= r) tmp[k++] = q[j++]; for(i = l, k = 0; i <= r; i++, k++) q[i] = tmp[k]; }
3、二分
整数二分:
二分的本质并不是单调性,但是有单调性一定可以二分
二分的本质是找到一个性质,使得右半边一定满足,左半边一定不满足。二分可以帮我们找到这个边界。
int bsearch_1(int l, int r) { while(l < r) { int mid = l + r >> 1; if(check(mid)) r = mid; else l = mid + 1; } return l; } int bsearch_2(int l, int r) { while(l < r) { int mid = l + r >> 1; if(check(mid)) l = mid; r = mid - 1; } return l; }