各种排序算法总结
1:合并排序
合并排序算法使用分治策略实现对n个元素进行排序的算法。其基本思想是:将待排序元素分成大小大致相同的两个子集合,分别对两个子集合进行排序,最后总将排好序的子集合合并成所要求的排好序的集合。算法描述如下:
void MergeSort(Typr a[],int left,int right)
{
if(left<right){ //至少有两个元素
int i=(left+right)/2; //取中点
MergeSort(a,left,i);
MergeSort(a.i+1,right);
Merge(a,b,left,i,right); //合并到数组b
Copy(a,b,left,right); //复制回数组a
}
}
void Merge(Type c[],Type d[],int l,int m,int r)
{
int i=l,j=m+1,k=1;
while((i<=m)&&(j<=r))
{
if(c[i]<=c[j]) d[k++]=c[i++];
else d[k++]=c[j++];
}
if(i>m) for(int q=j;q<=r;q++) d[k++]=c[q];
else for(int q=i;q<=m;q++) d[k++]=c[q];
}
时间复杂度:O(nlgn)
2:插入排序
插入排序比较简单,算法描述如下:
for j=2 to A.length
key=A[i];
i=j-1;
while i>0 and A[i]>k
A[i+1]=A[i];
i--;
A[i+1]=key;
时间复杂度:O(n²)
3:冒泡排序: O(n²)
每次相邻的两个数据进行比较,大的向下沉,小的向上升,像水中的气泡一样。 1 for(int i=0;i<n;i++)
for(int i=0;i<n;i++)
{
int k=i;
for(int j=i+1;j<n;j++)
{
if(A[j]<A[k]) k=j;
}
swap(A[i],A[k]);
}
4:选择排序:O(n²)
1 for(int i=0;in<n;i++) 2 { 3 for(int j=i+1;j<n;j++) 4 { 5 if(A[i]>A[j]) swap(A[i],A[j]); 6 } 7 8 }
5:堆排序:①把数组调整成一个最大堆 (从A[n/2]...1进行调整) A[i]的做节点是A[2i],右节点是A[2i+1]
②每次把对顶元素A[0]和A[n]进行交换,A[0]放到了正确的位置,然后n--,调整堆使其仍然成为一个最大堆重复②的操作直到得到结果
时间复杂度:O(nlgn)
6:快速排序:就不说什么了,时间复杂度O(nlgn)
1 void QuickSort(Type a[],int p,int r) 2 { 3 if(p<r) 4 { 5 int q=Partition(a,p,r); 6 QuickSort(a,p,q-1); 7 QuickSort(aa,q+1,r); 8 } 9 } 10 11 12 int Partition(Type a[],int p,int r) 13 { 14 int i=p,j=r+1; 15 Type x=a[p]; 16 while(true) 17 { 18 while(a[++i]<x&&i<r); 19 while(a[--j]>x); 20 if(i>=j) break; 21 Swap(a[i],a[j]); 22 } 23 a[p]=a[j]; 24 a[j]=x; 25 return j; 26 }
////线性时间排序
计数排序、计数排序、桶排序
计数排序:假设每个输入元素都是在0到k区间内的一个整数,当k=O(n)时,排序运行的时间Θ(n)
基数排序基本思想:对每一个输入元素x,确定小于x的元素的个数。利用这一信息,就可以直接把x放到它在输出数组中的位置上了。
伪代码:假设输入时一个数组A[1..n],A.length=n。我们需要两个数组:B[1..n]存放排序的输出,C[0..k]提供临时存储空间。
for i=0 to k //c的值全置0
c[i]=0;
for j=1 to A.length //c[i]等于i的元素的个数
c[A[j]]=C[A[j]]+1
for i=1 to k //c[i]记录有多少元素是小于等于i的
c[i]=c[i]+c[i-1]
for j=A.length downto 1
B[c[A[j]]]=A[j]
c[A[j]]=C[A[j]]-1
桶排序:假设输入数据服从均匀分布,平均情况下它的时间代价为O(n)
伪代码:假设输入是一个含有n个元素的数组A,切每个A[i]满足0<=A[i]<1一个临时数组B[0..n-1]来存放链表,并假设存在一种用于维护这些链表的机制
n=A.length let B[0..n-1] be a new array for i=0 to n-1 make B[i]an empty list //各个桶初始化为空 for i=1 to n insert A[i] into list B[nA[i]] //把数据插入到各个桶中 for i=0 to n-1 sort list B[i] with insertion sort //用插入排序对桶中的节点进行排序 concatenate lists B[0],B[1]...B[n-1]together in order //链接各个桶中的元素