第一章 基础算法(一)
排序
- 快排
- 归并
二分
- 整型
- 浮点型
快排
典型的分治算法:分、治、合
首尾交替法:设置两个指示器lo和hi,搜索从右边开始,找,直到找到一个
代码
#include <iostream>
using namespace std;
const int N = 100000;
int partition(int a[],int lo,int hi){
int pivot = a[lo];
while(lo<hi){
while(lo<hi && a[hi]>=pivot)
hi--;
a[lo] = a[hi];
while(lo<hi && a[lo]<=pivot)
lo++;
a[hi] = a[lo];
}
a[lo] = pivot;
return lo;
}
void quicksort(int a[],int lo,int hi){
if(lo<hi){
int pivot = partition(a,lo,hi);
quicksort(a,lo,pivot-1);
quicksort(a,pivot+1,hi);
}
}
int main(){
int a[N];
int n;
cin>>n;
for(int i = 0;i<n;i++){
scanf("%d",&a[i]);
}
quicksort(a,0,n-1);
for(int i = 0;i<10;i++){
printf("%d ",a[i]);
}
return 0;
}
AcWing 786.第k个数
归并排序
- 找到分点——中点
- 分别排序
- 两个结果并起来
- 两个指示器i和j指向两个结果的最小值,另外一个指示器k指向临时数组,每次将小者存入临时数组
- 应该有一段还没到尽头,继续存入
- 将临时数组复制到原数组中
代码
#include <iostream>
using namespace std;
const int N = 100000;
void mergeSort(int a[],int l,int r){
if(l>=r)return;
int mid = l + r >>1;
mergeSort(a,l,mid);
mergeSort(a,mid+1,r);
int tmp[N]; // 暂时存储我们归并的结果
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(){
int a[N];
int n;
cin>>n;
for(int i = 0;i<n;i++){
scanf("%d",&a[i]);
}
mergeSort(a,0,n-1);
for(int i = 0;i<n;i++){
printf("%d ",a[i]);
}
return 0;
}
AcWing 788.逆序对的数量
整数二分
情况一:
m i d = l + r + 1 2 mid = \frac{l+r+1}{2} mid=2l+r+1 区间分为[l,mid-1] 和 [mid,r]
check(mid):
- true:l = mid
- false:r = mid-1
情况二:
m i d = l + r 2 mid = \frac{l+r}{2} mid=2l+r 区间分为[l,mid] 和 [mid+1,r]
check(mid):
- true:r = mid
- false:l = mid+1
根据true是谁等于mid,再去修改mid
每次都选择答案所在的区间