2.1基础算法(排序)
1.快速排序:基本思想是分治,时间复杂度nlog(n)
1)确定分界点
2)调整区间
3)递归处理左右两段
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 100010;
int a[N];
void quick_sort(int a[] , int l , int r){
if(l>=r) return ;
int x = a[l+r>>1], i = l - 1 , j = r + 1;
while(i<j){
do i++; while(a[i]<x);//可以写while(a[++1]<x),适于没有do-while的语言
do j--; while(a[j]>x);
if(i<j) swap(a[i],a[j]);
}
quick_sort(a,l,j);
quick_sort(a,j+1,r);
}
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
quick_sort(a,0,n-1);
for (int i = 0; i < n; i ++ ) printf("%d ", a[i]);
return 0;
}
2.归并排序 基本思想:分治 , 时间复杂度nlog(n)
1)确定分界点mid = (l + r)/2 ,和快速排序的区别是快排的分界点是值,归并的分界点是数组下标
2)递归排序左边和右边
3)合并
#include <iostream>
using namespace std;
const int N = 100010;
int a[N],tmp[N];
void merge_sort(int a[] , int l , int r){
if(l>=r) return;
int mid = l+r>>1;
merge_sort(a,l,mid);
merge_sort(a,mid+1,r);
int k = 0 , i = l , j = mid+1;
while(i<=mid and 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(int i = l , j = 0 ; i <= r ; i++ , j++) a[i]=tmp[j];
}
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
merge_sort(a,0,n-1);
for (int i = 0; i < n; i ++ ) printf("%d ",a[i]);
return 0;
}
3)二分
找到的是从左往右第一个满足>=x的数
整数二分:
#include <iostream>
using namespace std;
const int N = 100010;
int a[N];
int main()
{
int n,m;
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
while (m -- ){
int x;
scanf("%d", &x);
int l = 0 , r = n-1;
while(l<r){
int mid = l+r>>1;
if(a[mid]>=x) r = mid;
else l = mid+1;
}
if(a[l]!=x) printf("-1 -1\n");
else{
printf("%d ",l);
int l = 0 , r = n-1;
while(l<r){
int mid = l+r+1>>1;
if(a[mid]<=x) l = mid;
else r = mid-1;
}
printf("%d\n",l);
}
}
return 0;
}
浮点数二分:
输入浮点数x,找到x的平方根,结果保留6位小数
#include <iostream>
using namespace std;
int main()
{
double x;
scanf("%lf", &x);
double l = 0 , r = x;
while(r-l>1e-8){
double mid = (l+r)/2;
if(mid*mid>=x) r = mid;
else l = mid;
}
printf("%.6lf\n",l);
return 0;
}
保留几位小数,循环的时候就多写两位,比如6位小数写1e-8 ;