1 快速排序
void quicksort(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);
do j--;
while (a[j] > x);
if (i<j)swap(a[i], a[j]);
}
quicksort(a, l, j); //x有+1的时候为i-1,i 没有为j,j+1
quicksort(a, j+1, r);
}
2 归并排序
void merge(int a[],int l,int r)
{
if(l>=r)
return ;
int mid=(l+r)>>1;、
merge(a,l,mid);
merge(a,mid+1,r);
int i=l,j=mid+1;
for(int k=l;k<=r;k++)
{
if(j>r||i<=mid&&a[i]<=a[j])
b[k]=a[i++];
else
b[k]=a[j++];
}
for(int k=l;k<=r;k++)
a[k]=b[k];
}
3 离散化
当数组下标过大或蕴含负数,而我们只需使用其中有限个的信息时
vector<int> vi;
void lisan()
{
sort( vi.begin(), vi.end() );
erase( unique( vi.begin(), vi.end() ), vi.end() );
}
int find(int x)
{
return lower_bound( vi.begin(), vi.end(), x ) - vi.begin();
}
4 第k大的数
快排的每一趟,基准左边 <= x ,右边 >= x
左边元素的个数 s1 = j - l + 1, 如果k <= s1 ,
下次递归的区间就是左边,否则右边
5 逆序对
归并排序中是比较a[i]和a[j]的大小,小的放在前面,
如果a[j]比a[i]小,则a[i]中mid+1-i个都可与a[j]构成逆序对