快速排序
-
主要思想:分治
-
稳定性:不稳定
-
时间复杂度:最好情况下
;最差情况下:
-
解题步骤:
- 确定分界点 q[l]、q[(l+r)/2]、q[r] 随机 (l:左端点;r:右端点)
- 调整区间 分为两个区间,保证左区间的数都≤x ,右区间的数都≥x
- 递归处理左右两端 对两个区间按从小到大排序(左区间的最大值≤右区间的最小值)
#include<iostream> using namespace std; const int N = 1e6+10; int n; int q[N]; void quick_sort(int q[], int l, int r) { if(l>=r) return; // 只含一个数的数组 / 空数组 int x = q[l]; int i = l-1; int 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, j); quick_sort(q, j+1, r); } int main() { scanf("%d", &n); for(int i=0; i<n; i++) scanf("%d", &q[i]); quick_sort(q, 0, n-1); for(int i=0; i<n; i++) printf("%d", q[i]); return 0; }
归并排序
-
主要思想:分治
-
稳定性:稳定
-
时间复杂度:O(nlogn) 。
-
解题步骤:
- 确定分界点 mid=(l+r)/2
- 递归排序 left right
- 归并 合二为一
#include<iostream> using namespace std; const int N = 1e+10; int n; int q[N],tmp[N]; void merge_sort(int q[], int l, int r) { if(l>=r) return; int mid = l+r >> 1; // 等同于 (l+r)/2 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(int i = l,j = 0; i<=r; i++,j++) q[i] = tmp[j]; } int main() { scanf("%d", &n); for(int i = 0; i<n; i++) scanf("%d",&q[i]); merge_sort(q,0,n-1); for(int i = 0; i<n ;i++) printf("%d",q[i]); return 0; }
二分查找
整数二分
#include<iostream>
using namespace std;
const int N = 100010;
int n, m; // n:数组个数 m:查询次数
int q[N];
int main()
{
scanf("%d%d", &n, &m);
for(int i = 0; i<n; i++) scanf("%d", &q[i]);
while(m--)
{
int x;
scanf("%d", &x); // x:要查找的数
// 寻找左边界
int l = 0, r = n-1;
while(l<r) // 当区间[l,r]被划分为[l,mid]和[mid+1,r]时使用
{
int mid = l + r >> 1;
if(q[mid] >= x) r = mid;
else l = mid + 1;
}
if(q[l] != x) cout<< "-1 -1" << endl;
else
{
cout<< l << ' ';
// 寻找右边界
int l = 0, r = n-1;
while(l<r) // 当区间[l,r]被划分为[l,mid-1]和[mid,r]时使用
{
int mid = l + r + 1 >> 1;
if(q[mid] <= x) l = mid;
else r = mid - 1;
}
cout<< l << endl;
}
}
return 0;
}
浮点数二分
求某个数的平方根
#include<iostream>
using namespace std;
int main()
{
double x;
cin>>x;
double l = -10000, r = 10000;
while(r - l > 1e-8)
{
double mid = l + r >> 1;
if(mid * mid >= x) r = mid;
else l = mid;
}
printf("%lf\n", l); // %f => float ; %lf => double,默认保留6位 ; %.2lf => 保留2位
return 0;
}