一说到快排,一群人开始说,你怎么不用sort,这不是傻不傻的问题,因为面试让你手写个快排,你总不能给面试官sort吧,所以思想很重要,这就是最简单的基础
#include<iostream>
using namespace std;
const int N=100010;
int a[N];
void qsort(int l,int r)
{
if(l>=r)return;
int i=l-1,j=r+1;
int mid=(a[l+r>>1]);//注意这边容易出现边界问题
while(i<j)
{
do i++;while(a[i]<mid);
do j--;while(a[j]>mid);
if(i<j)swap(a[i],a[j]);
}
qsort(l,j),qsort(j+1,r);//要是mid=a[l]
//则sort递归l,j;j+1,r
//否则递归l,i-1;i,r
}
int main()
{
int n;cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
qsort(1,n);
for(int i=1;i<=n;i++)
cout<<a[i]<<' ';
cout<<endl;
return 0;
}
//2021-07-05/17:57
#include<iostream>
using namespace std;
int n;
const int N = 1e6+10;
int a[N] , tem[N];
void msort(int l , int r)
{
if(l >= r)return;//保证回溯的过程也就是递归基
int mid = l+r >> 1;
msort(l , mid) , msort(mid+1 , r);
int k = 0 , i = l , j = mid+1;
while(i <= mid && j <= r)
{
if(a[i] <= a[j])tem[k++] = a[i++];
else tem[k++] = a[j++];
}
while(i <= mid)tem[k++] = a[i++];
while(j <= r)tem[k++] = a[j++];
for(int i = l , j = 0 ; i <= r ; i++ , j++)a[i] = tem[j];
}
int main()
{
cin >> n;
for(int i = 0 ; i < n ; i++)
cin >> a[i];
msort(0 , n-1);
for(int i = 0 ; i < n ; i++)
cout << a[i] << ' ';
cout << endl;
return 0;
}
//2021-07-06/11:17
- 可以用来求逆序对的数量,这是归并排序的一个拓展
#include<iostream>
using namespace std;
typedef long long LL;
const int N=1e6+10;
int a[N],tmp[N];
int n;
LL ans;
LL msort(int l,int r)
{
if(l>=r)return 0;
int mid=l+r>>1;
msort(l,mid),msort(mid+1,r);
int k=0,i=l,j=mid+1;
while(i<=mid&&j<=r)
{
if(a[i]<=a[j])tmp[k++]=a[i++];
else
{
tmp[k++]=a[j++];
ans+=mid-i+1;
}
}
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];
return ans;
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
cout<<msort(0,n-1)<<endl;
return 0;
}
int l = 0, r = n - 1;
while (l < r)
{
int mid = l + r >> 1;
if (a[mid] >= x)r = mid;//向下二分找lower
else l = mid+1;
}
- 但要是是寻找num出现的最后一个位置也就是upper_bound(a,a+n,num)就相对更加难以实现,适用于将区间分为l , mid-1~mid , r
int l = 0, r = n - 1;
while (l < r)
{
int mid = l + r + 1 >> 1;
if (a[mid] <= x) l = mid;//向上二分找upper
else r = mid - 1;
}
- 所以算法一找的是大一等于x的最小元素的位置与lower_bound()不谋而合,算法二找的是大于x的第一个位置与upper_bound()不谋而合,也就是其的内部实现
-
!注意:两个函数返回的都是地址,要是想返回数组下标最好减去首地址,或者取地址返回元素值
-
4、浮点数二分
- 牢记一点经验值,要是保留四位小数循环的时候写成
while(r - l < 1e - 6)