1.插入排序
平均时间复杂度O(n^2),最优时间复杂度O(n),最差时间复杂度O(n^2),空间复杂度O(1),稳定。
void insertionSort(int *A,int n)
{
for(int j=1;j<n;++j)
{
int key=A[j],i=j-1;
for(;i>=0&&A[i]>key;--i)A[i+1]=A[i];
A[i+1]=key;
}
}
二分插入排序(折半插入排序)
稳定。
void binaryInsertionSort(int *A,int n)
{
for(int j=1;j<n;++j)
{
int key=A[j],left=0,right=j-1;
while(left<=right)
{
int mid=left+(right-left)/2;
if(A[mid]<key)left=mid+1;
else if(A[mid]>key)right=mid-1;
else
{
int i=mid+1;
for(;i<=j-1&&A[i]==key;++i);
left=i;
break;
}
}
for(int i=j-1;i>=left;--i)A[i+1]=A[i];
A[left]=key;
}
}
希尔排序(缩小增量排序)
不稳定。
void shellSort(int *A,int n)
{
for(int inc=n/2;inc;inc/=2)
{
for(int j=inc;j<n;j+=inc)
{
int key=A[j],i=j-inc;
for(;i>=0&&A[i]>key;i-=inc)A[i+inc]=A[i];
A[i+inc]=key;
}
}
}
2.归并排序
平均时间复杂度O(nlogn),最优时间复杂度O(n),最差时间复杂度O(nlogn),空间复杂度O(n),稳定。
void merge(int *A,int p,int q,int r)
{
int n1=q-p+1,n2=r-q;
int *L=new int[n1+1],*R=new int[n2+1];
for(int i=0;i<n1;++i)L[i]=A[p+i];
for(int i=0;i<n2;++i)R[i]=A[q+1+i];
L[n1]=R[n2]=INT_MAX;
int i=0,j=0;
for(int k=p;k<=r;++k)
{
if(L[i]<=R[j])A[k]=L[i++];
else A[k]=R[j++];
}
delete [] L,R;
}
void mergeSort(int *A,int p,int r)
{
if(p<r)
{
int q=p+(r-p)/2;
mergeSort(A,p,q);
mergeSort(A,q+1,r);
merge(A,p,q,r);
}
}
3.堆排序
时间复杂度O(nlogn),空间复杂度O(1),不稳定。
void maxHeapify(int *A,int n,int i)
{
int l=2*i+1,r=l+1,largest=i;
if(l<n&&A[l]>A[i])largest=l;
if(r<n&&A[r]>A[largest])largest=r;
if(largest!=i)
{
swap(A[i],A[largest]);
maxHeapify(A,n,largest);
}
}
void buildMaxHeap(int *A,int n)
{
for(int i=n/2-1;i>=0;--i)maxHeapify(A,n,i);
}
void heapSort(int *A,int n)
{
buildMaxHeap(A,n);
for(int i=n-1;i>=1;--i)
{
swap(A[0],A[i]);
maxHeapify(A,i,0);
}
}
4.快速排序
平均时间复杂度O(nlogn),最优时间复杂度O(nlogn),最差时间复杂度O(n^2),空间复杂度从O(logn)到O(n),不稳定。
int partition(int *A,int p,int r)
{
int x=A[r],i=p-1;
for(int j=p;j<r;++j)
{
if(A[j]<=x)swap(A[++i],A[j]);
}
swap(A[i+1],A[r]);
return i+1;
}
void quickSort(int *A,int p,int r)
{
if(p<r)
{
int q=partition(A,p,r);
quickSort(A,p,q-1);
quickSort(A,q+1,r);
}
}
5.冒泡排序
时间复杂度O(n^2),空间复杂度O(1),稳定。
void bubbleSort(int *A,int n)
{
for(int i=0;i<=n-2;++i)
{
for(int j=0;j<=n-2-i;++j)
{
if(A[j]>A[j+1])swap(A[j],A[j+1]);
}
}
}
6.选择排序
时间复杂度O(n^2),空间复杂度O(1),不稳定。
void selectionSort(int *A,int n)
{
for(int i=0;i<=n-2;++i)
{
int min=i;
for(int j=i+1;j<=n-1;++j)
{
if(A[j]<A[min])min=j;
}
swap(A[i],A[min]);
}
}
7.计数排序
时间复杂度O(n+k),空间复杂度O(n+k),稳定。
void countingSort(int *A,int *B,int n,int k)
{
int *C=new int[k+1]();
for(int i=0;i<n;++i)++C[A[i]];
for(int i=1;i<=k;++i)C[i]+=C[i-1];
for(int i=n-1;i>=0;--i)
{
B[C[A[i]]-1]=A[i];
--C[A[i]];
}
delete [] C;
}
8.基数排序
时间复杂度O(kn),空间复杂度O(kn),稳定。
void radixSort(int *A,int n,int k)
{
int *B=new int[n],*C=new int[10](),radix=1;
for(int i=0;i<k;++i)
{
for(int i=0;i<n;++i)++C[A[i]/radix%10];
for(int i=1;i<10;++i)C[i]+=C[i-1];
for(int i=n-1;i>=0;--i)
{
B[C[A[i]/radix%10]-1]=A[i];
--C[A[i]/radix%10];
}
for(int i=0;i<n;++i)A[i]=B[i];
radix*=10;
}
delete [] B,C;
}
9.桶排序
时间复杂度O(n),空间复杂度O(n),稳定。
struct node
{
double value;
node *next;
node(double x=-1):value(x),next(NULL){}
};
void bucketSort(double *A,int n)
{
node *B=new node[n];
for(int i=0;i<n;++i)
{
node *p=new node(A[i]),*prev=B+int(floor(n*A[i])),*cur=prev->next;
for(;cur&&cur->value<=A[i];prev=cur,cur=cur->next);
p->next=cur;
prev->next=p;
}
for(int i=0,j=0;i<n;++i)
{
for(node *cur=B[i].next;cur;A[j++]=cur->value,cur=cur->next);
}
delete [] B;
}