快排代码:
#include <iostream> using namespace std; const int N = 1e6+1; int a[N]; void qsort(int l,int r) { if(l >= r) return ; int i = l -1, j = r+1,x = a[l+r>>1]; while(i < j) { do i++;while(a[i] < x); do j--;while(a[j] > x); if(i < j) swap(a[i],a[j]); } qsort(l,j);qsort(j+1,r); } int main() { std::ios::sync_with_stdio(false); int n; cin>>n; for(int i = 0;i<n;i++) cin>>a[i]; qsort(0,n-1); for(int i = 0;i<n;i++) cout<<a[i]<<" "; return 0; }
快排如果要把j换成i的话,qsort(l, i-1);qsort(i,r);那么设定的比较的数字就不能是q[l]。int x = q[r];
当用j作为边界的时候:qsort(l,j);qsort(j+1,r);那么设定的比较数字就不能是q[r];int x = q[l];
归并排序代码:
#include <iostream> using namespace std; const int N = 1e6+10; int a[N],tmp[N]; void qsort(int l,int r) { if(l >= r) return; int mid = l + r >> 1; qsort(l,mid);qsort(mid+1,r); int i = l,j = mid+1,k = 0; while(i <= mid && j <= r) { if(a[i] <= a[j]) tmp[k++] = a[i++]; else tmp[k++] = a[j++]; } while(i <= mid) tmp[k++] = a[i++]; while(j <= r) tmp[k++] = a[j++]; for(i = l,j=0;i<=r;i++,j++) a[i] = tmp[j]; } int main() { std::ios::sync_with_stdio(false); int n; cin>>n; for(int i = 0;i<n;i++) cin>>a[i]; qsort(0,n-1); for(int i = 0;i<n;i++) cout<<a[i]<<" "; return 0; }
比较sort函数、快排、归并三种排序方式耗时,——>>发现三者其实所耗的时间相差无几。
二分:
整数二分:
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) >> 1; if(check(mid)) l = mid; else r = mid - 1; } return l; }
整数查询开始位置和结束的位置:
#include <iostream> using namespace std; const int N = 100010; int 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); int l = 0, r = n - 1; while(l < r) { int mid = (l + r) >> 1; if(q[mid] >= x) r = mid;//找到左边第一个出现x的位置,若中点都大于x,那么起始点肯定在左侧,就令r = mid; else l = mid + 1; } if(q[l] != x) cout<<"-1 -1"<<endl;//如果x不存在,那么找到的是第一个>=x的数字 else { cout<<l<<' ';//先找到x开始的位置输出 int l = 0, r = n - 1; while(l < r) { int mid = (l + r + 1) >> 1; if(q[mid] <= x) l = mid;//找到最后一个出现x的位置,若中点的位置都<=x,那么x结束的位置肯定在mid的右半部分,所以令l = mid; else r = mid - 1; } cout<<l<<endl; } } return 0; }
浮点数二分:
#include <iostream> using namespace std; int main() { double x; cin>>x; double l = -1e5, r = 1e5; while(r - l > 1e-8) { double mid = (l + r) / 2; if(mid * mid * mid >= x) r = mid; else l = mid; } printf("%.6lf ",l); return 0; }
不用精度,而是直接循环一百次:
#include <iostream> using namespace std; int main() { double x; cin>>x; double l = -1e5, r = 1e5; for(int i = 0;i<100;i++) { double mid = (l + r) / 2; if(mid * mid * mid >= x) r = mid; else l = mid; } printf("%.6lf ",l); return 0; }