四种nlogn排序算法代码
1.快速排序:不稳定排序,最好情况O(nlogn),最差情况O(n^2).平均情况在所有nlogn排序中最快的排序
快速排序分两步
第一步是将l-r区间进行分块(假设将区间最后一个作为关键字)前面一块的数比小于等于关键字,后面一块大于关键字,并返回第一个大于关键字的位置,即函数partition
第二部是对l~pos-1 和pos+1~r分别进行快速排序.
递归式:
int partition(int l,int r)
{
int k=r;
while(l<r)
{
int c=0;
if(a[l]<=a[k])
l++;
else
c++;
if(a[r]>=a[k])
r--;
else
c++;
if(c==2)
{
int tem=a[l];
a[l]=a[r];
a[r]=tem;
}
}
if(l==r)
{
if(a[k]>=a[r])
return r+1;
else
return r;
}
else
return l;
}
void quicksort(int l,int r)
{
if(l>=r)
return;
int pos;
pos=partition(l,r);
int val=a[r];
a[r]=a[pos];
a[pos]=val;
quicksort(l,pos-1);
quicksort(pos+1,r);
}
非递归式:
用栈实现,在函数各种变量和参数不是很多的情况下用递归式比较好
详细看网上
2.shell排序:不稳定排序,最好情况O(nlogn),最差情况O(n^x),1<x<2
变长度的插入排序,分别对原数组进行k次长度不同的插入排序即可,注意:最后一次必须是长度为1的插入排序
void shellsort()
{
for(int i=0;i<=x;i++)//x代表长度的组数
{
for(int j=len[i];j<n;j++)//此处是j++而不是j+=len[i]注意!!,希尔排序变长度的排序思想
{
int k=j-len[i];
while(k>=0)
{
if(a[j]<a[k])
{
int tem=a[j];
a[j]=a[k];
a[k]=tem;
break;
}
else
k-=len[i];
}
}
}
}
3.堆排序:不稳定排序,最好和最坏的时间复杂度均为O(nlogn):
主要是写向下渗透函数,然后注意:
1.当数组从0开始左儿子为2*x+1,右儿子为2*x+2
递归返回条件i》(x+1)/2-1
2.当数组从1开始左儿子为2*x,右儿子为2*x+1
递归返回条件i》(x+1)/2
class heaps
{
public:
int heap[50]={9,8,7,6,5,4,3,2,1,34,5,6,74,24,5,1,2,3,4,55,21,13,41,3};
int maxsize=23;
void godown(int i,int x)
{
if(i>(x+1)/2-1)//返回条件,易错点
return;
int MAX;
int j;
if(i*2+2>x)//当只有左孩子的情况!!易错点
{
MAX=heap[i*2+1];
j=i*2+1;
}
else//有两个孩子的情况
{
if(heap[i*2+1]>heap[i*2+2])
{
MAX=heap[i*2+1];
j=i*2+1;
}
else
{
MAX=heap[i*2+2];
j=i*2+2;
}
}
if(MAX>heap[i])
{
heap[j]=heap[i];
heap[i]=MAX;
godown(j,x);
}
}
void buildheap()
{
for(int i=(maxsize+1)/2-1;i>=0;i--)
godown(i,maxsize);
}
void heapsort()
{
int k=maxsize;
for(int i=1;i<=maxsize;i++)
{
int tem=heap[k];
heap[k]=heap[0];
heap[0]=tem;
k--;
godown(0,k);//注意,堆的大小在不断变化
}
}
};
4.归并排序:稳定排序,最好和最坏的时间复杂度均为O(nlogn)
void merge(int* a,int l,int r)
{
int tem[100];
int mid=(l+r)/2;
int i=l;
int j=mid+1;
int k=l;
for(;i<=mid+1||j<=r+1;i++,j++)
{
if(i==mid+1&&j==r+1)
break;
if(i==mid+1)
{
tem[k++]=a[j];
i--;
continue;
}
if(j==r+1)
{
tem[k++]=a[i];
j--;
continue;
}
if(a[i]<a[j])
{
tem[k++]=a[i];
j--;
}
else
{
tem[k++]=a[j];
i--;
}
}
}
void merge_sort(int* a,int l,int r)
{
int mid=(l+r)/2;
if(mid+1>r)
return;
merge_sort(a,l,mid);
merge_sort(a,mid+1,r);
merge(a,l,r);
}
此外还有3种O(n^2)的排序,不详细介绍
1.选择排序:不稳定,时间复杂度 O(n^2)
2.插入排序:稳定,时间复杂度 O(n^2)
3.冒泡排序:稳定,时间复杂度 O(n^2)