基于分治
快排是先分完再递归两边
归并是先递归,后合二为一
快速排序
在每一轮挑选一个基准元素,并让其他比它大的元素移动到数列一边,比它小的元素移动到数列的另一边,从而把数列拆解成了两个部分。
- 找一个参照点x
- 让x的左边都小于x,右边都大大于x
以 J 为中点,递归左边和右边
void quick_sort(int q[], int l, int r){if (l >= r) return; //只有一个或为零时,结束int i = l - 1, j = r + 1, x = q[l + r >> 1]; // 这里的-1和+1会在下面的do循环中去掉while (i < j){do i ++ ; while (q[i] < x); // 找到左边比x大(>=)的数do j -- ; while (q[j] > x); // 找到右边比x小(<=)的数if (i < j) swap(q[i], q[j]); //判断是否左边小于右边,然后交换}quick_sort(q, l, j), quick_sort(q, j + 1, r); //递归左右两边}
归并排序
[L,R] => [L,mid] , [mid+1,R] ;
- 递归排序[L,mid]和[mid+1,R];
归并,将左右两个有序序列合并成一个有序序列;
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) //将这两个数进行比较//tem是一个临时数组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 ++ ];//再改变q数组for (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];}
