排序
快排(quick_sort)
(1)、确立分界点(最后分界点不一定等于x,因为可能会有几个相同数值的值,只是中间位置不是中间值)
(2)、调整区间
(3)、递归处理左右两端
1、暴力解法
2、双指针扫描:左端指针右端指针相互扫描,两指针交换后都移动一格,直到指针相遇或者i>j时停止扫描。然后把两段区间代入这个函数模块,因为都是基于数组q的操作,所以最后得到有序的q数组。
AcWing 785. 快速排序算法的证明与边界分析 - AcWing
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];
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, j), quick_sort(q, j + 1, r);
}
if (i < j)swap(q[i], q[j]);
为什么要交换两个指针指向的数值呢?
当i指向的值大于x,j指向的值小于x的时候,这个时候两指针指向的数值相互交换,实现数组的有序,实现调整区间。
归并(merge_sort)
归并需要占用更多的额外空间,一般用于大数据的外部排序
(1)、找出数组中间值
(2)、对左、右段进行递归排序
(3)、归并(合二为一)
双指针都指向左右最小端,然后双指针相比较,数值较小的指针指向的数值重新排入新数组,然后更小值的指针移位,当两指针数组相同时都可以移位,但通常是上指针移位,当有一个指针遍历完全后退出循环。
int tmp[N]; //归并算法需要重新定义一个数组来容纳合并后的数值
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);
//变量k是给新数组tmp的标
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 ++ ];
//当结束遍历后,看是左段还是右段有剩余,把剩余数直接赋给tmp
while (i <= mid) tmp[k ++ ] = q[i ++ ];
while (j <= r) tmp[k ++ ] = q[j ++ ];
//最后再把数组tmp[]赋给数组q[]
for (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];
}
二分
高精度
疑问和知识点杂记
疑问
1、c++数组指针的问题
2、函数局部变量和全局变量
3、const用法
const是定义常量,不加const,N就是变量,c++定义数组必须用常量
4、vector用法
5、什么时候写函数加返回值什么条件不加返回值呢?void空函数和其他函数
知识点杂记
1、(l+r)/ 2等价于l+r>>1,二进制进位并且速度更快