快速排序
(l+r)>>1在奇数长度数组的中间,偶数长度数组的左半边最后一个,极限情况下数组只有两个数,i遇到第一个数就会停下,此时模拟i,j下标的数有无交换的情况,会发现j在停下来时都位于第一个数的位置,因此用j,j+1才不会越界
(l+r+1)>>1在奇数长度数组的中间往右第一个,偶数长度数组的右半边第一个,极限情况下数组只有两个数,当没有交换时,i走到最后一个数才停下,j停在最后一个数,因此用i-1,i才不会越界
#include<iostream>
using namespace std;
const int N=1e8+10;
int a[N];
void quick_sort(int l,int r)
{
if(l>=r)return;
int i=l-1,j=r+1,x=a[l+r>>1];
while(i<j)
{
while(a[++i]<x);
while(a[--j]>x);
if(i<j)swap(a[i],a[j]);
}
quick_sort(l,j);
quick_sort(j+1,r);
}
int main()
{
int n;
cin>>n;
for(int i=0;i<n;++i)
cin>>a[i];
quick_sort(0,n-1);
for(int i=0;i<n;++i)
cout<<a[i]<<" ";
puts("");
return 0;
}
归并排序
#include<iostream>
#include<cstdio>
using namespace std;
const int N=1e8+10;
int a[N],t[N];
void merge_sort(int l,int r)
{
if(l>=r)return;
int mid=l+r>>1;
int i=l,j=mid+1,k=0;
merge_sort(l,mid);
merge_sort(mid+1,r);
while(i<=mid&&j<=r)
{
if(a[i]<=a[j])t[k++]=a[i++];
else t[k++]=a[j++];
}
while(i<=mid)t[k++]=a[i++];
while(j<=r)t[k++]=a[j++];
for(i=l,j=0;i<=r;++i,++j)
a[i]=t[j];
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;++i)
scanf("%d",&a[i]);
merge_sort(0,n-1);
for(int i=0;i<n;++i)
printf("%d ",a[i]);
puts("");
return 0;
}
堆排序
先输入再建堆
#include<iostream>
#include<cstdio>
using namespace std;
const int N=1e8+10;
int len,a[N];
void down(int x)
{
while(x<=len)
{
int t=x;
if(2*x<=len&&a[t]>a[2*x])
t=2*x;
if(2*x+1<=len&&a[t]>a[2*x+1])
t=2*x+1;
if(t==x)break;
swap(a[x],a[t]);
x=t;
}
}
int main()
{
int n;
scanf("%d",&n);
len=n;
for(int i=1;i<=n;++i)
scanf("%d",&a[i]);
for(int i=n/2;i;--i)
down(i);
while(n--)
{
printf("%d ",a[1]);
a[1]=a[len--];
down(1);
}
puts("");
return 0;
}
边输入边建堆
#include<iostream>
#include<cstdio>
using namespace std;
const int N=1e8+10;
int len,a[N];
void down(int x)
{
while(x<=len)
{
int t=x;
if(2*x<=len&&a[t]>a[2*x])
t=2*x;
if(2*x+1<=len&&a[t]>a[2*x+1])
t=2*x+1;
if(t==x)break;
swap(a[x],a[t]);
x=t;
}
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
scanf("%d",&a[i]);
++len;
if(i>1)down(i/2);
}
while(n--)
{
printf("%d ",a[1]);
a[1]=a[len--];
down(1);
}
puts("");
return 0;
}