一 : 快速排序 (分治)
备注:
O(nlogn)-O(nn)
过程:
1. 确定分界点 1 r (1+r)/2
2. 调整范围 核心
3. 递归处理左右两段
我们从中应该了解到:
1. 边界思想
(1)表面上看起来很平常,其实很重要 ,处理不当就废了
(2)也为递归创造了结束条件
2. 双指针
(1)数据可以从两边同时处理
3. 分界点选取
4. 递归
void quickSort(int q[],int l,int r){
if( l >= r ) return;// 边界判断
int x = q[l] ; //取分界点 一般取中间 或者 开头 或者 结尾
int i = l - 1 ,j = r + 1; //指针
while( i < j ){ //移动交换算一次迭代
do i++ ; while( q[i] < x ); //i一直往后移 直到 q[i] >= x
do j-- ; while( q[j] > x ); //j一直往前移 直到 q[j] <= x
if( i < j ) swap( q[i] , q[j] ); // 交换各取所需
}
quickSort( q , l , j );
quickSort( q , j+1 , r);
}
二:归并排序(分治)
备注:
O(nlogn) n除多少次除成1 -> logn次 (层) O(n)
过程:
1.确定分界点 mid = (1+r) /2
2.递归排序 left right
3.归并(合二为一) 核心 O(n)
我们从中应该学习到的东西:
1. 双指针
2. 递归
3. 位运算
void mergeSort(int q[],int l ,int r){
if ( l >= r) return;
int mid = l + r >> 1; //取中点
mergeSort( q , l , mid ); mergeSort( q , mid + 1 , r); // 递归
int k = 0, i = l, j= mid + 1;
while(i <= mid && j <= r) //归并
if(q[i] <= q[j]) temp[k++] = q[i++];
else temp[ k ++ ] = q[ j ++];
while(i <= mid) temp[ k ++ ] =q[ i ++ ];
while(j <= r) temp[ k ++ ] =q[ j ++ ];
for( i = l, j = 0 ; i <= r ; i ++,j ++) q[i] = temp[j];
}
三:二分算法
整数(浮点)二分:
本质:
区间中定义某种性质,使得 右区间满足,左区间不满足
二分可以寻找边界 有左区间结尾模板 和右区间开头模板
模板:
右
1.mid = ( l+r +1 ) / 2
check(mid) ->true [mid,r] l=mid
check(mid) ->false [1,mid-1] r=mid-1
左
2.mid =( l+r ) / 2
check(mid) -> true [1,mid] r=mid
check(mid) -> false [mid+1,r] l=mid+1
选择: 先写 check()
若 l=mid 则 mid 写成 l+r+1 >>1
若 r=mid 则 mid 写成 l+r >>1
发现: l+r >>1 和 (l+r)>>1 结果是一样的
l+r+1 >>1 和 (l+r+1) >>1 结果是一样的
位运算的优先级太低了 几乎就是要最后运算
// 区间 [1,r]被划分成[1,mid]和[mid+1,r]时使用
int BSearch_1(int l,int r){
while( l < r ){
int mid = l + r >> 1;
if( check(mid) ) r = mid; // check() 判断 mid 是否满足性质
else l = mid + 1;
}
return l;
}
// 区间[1,r] 被划分成[1,mid-1]和[mid,r]时使用
int BSearch_2(int l,int r){
while( l < r ){
int mid = l + r + 1 >> 1;
if( check(mid) ) l = mid;
else r = mid - 1;
}
return l;
}
/**
1.无需考虑边界
2.距离满足一个很小的数字就行
或者 迭代很多次数
3.经验 1e-8 得到的是6位小数
1e-6 得到的是4位小数
**/
double BSearch_float(double r,double l){
while(r-l >1e-8){
double mid = ( l + r ) / 2;
if( check(mid) ) r = mid;
else l = mid;
}
return l;
}