排序算法总结以及实现。
#include <iostream>
using namespace std;
/*
直接插入排序,主要是找到需要插入位置,while循环就是为了找到插入位置。
数组存放从1开始。
算法是稳定的。
性能分析:最佳情况为输入数组已经排好序 O(n),最差为逆序O(n^2);
*/
void Insert_Sort(int *array,int len)
{
for (int j=2;j<=len;j++)
{
int key=array[j];
int i;
i=j-1;
while (i>0&&array[i]>key)
{
array[i+1]=array[i];
i--;
}
array[i+1]=key;
}
}
void swap(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
}
/*
直接选择排序实现,找到最小的放在1位置,以此类推操作后面知道倒数第二个数,此时数组排序完成。
从1开始存
算法稳定性:不稳定。如下例
排序前:
2,4,4*,3
排序后:
2,3,4*,4
时间复杂度:O(n^2)
*/
void Select_Sort(int *array,int len)
{
int i,j,m;
for (i=1;i<len;i++)
{
m=i;
for (j=i+1;j<=len;j++)
{
if (array[j]<array[m])
{
m=j;
}
}
if (m!=i)
{
swap(array[i],array[m]);
}
}
}
void merge(int *array,int start,int middle,int end)
{
int len1=middle-start+1;
int len2=end-middle;
int *L=new int[len1+1];
int *R=new int[len2+1];
int i,j,k;
for (i=1;i<=len1;i++)
{
L[i]=array[start+i-1];
}
for (j=1;j<=len2;j++)
{
R[j]=array[middle+j];
}
i=j=1;
//k的初始存放位置一定是start开始
k=start;
while (i<=len1&&j<=len2)
{
if (L[i]>=R[j])
{
array[k++]=R[j];
j++;
}
else
{
array[k++]=L[i];
i++;
}
}
while(i<=len1)
{
array[k++]=L[i++];
}
while (j<=len2)
{
array[k++]=R[j++];
}
}
/*
归并排序:递归到单个元素,然后合并
稳定排序。
复杂度当规模足够大时为O(lgn),最坏情况下要比插入排序(O(n^2))好。
*/
void Merge_Sort(int *array,int start,int end)
{
if(start<end)
{
int middle=(start+end)/2;
Merge_Sort(array,start,middle);//递归到左边单个元素
Merge_Sort(array,middle+1,end);//递归到右边单个元素
merge(array,start,middle,end);//合并两个有序的部分
}
}
/*
冒泡排序思想每次把最小的元素气泡一样浮起到上面
稳定排序
复杂度:O(n^2)
如果序列已经有序冒泡排序不会时间有优化。
*/
void Bubble_Sort(int *array,int len)
{
int i,j;
for (i=1;i<=len;i++)
{
for (j=len;j>=i+1;j--)
{
if (array[j]<array[j-1])
{
swap(array[j],array[j-1]);
}
}
}
}
int partition(int *array,int low,int high)
{
int pivotkey=array[low];
while (low<high)
{
while (low<high&&array[high]>=pivotkey)
{
high--;
}
array[low]=array[high];
while (low<high&&array[low]<=pivotkey)
{
low++;
}
array[high]=array[low];
}
array[low]=pivotkey;
return low;
}
/*
时间复杂度:最坏情况是划分不对称退化为插入排序效率,为O(n^2)
最好情况为每次划分平均,为O(nlgn)
不是稳定排序算法:例如5 3 3 4 3 8 9 10 11 partition后发现最后一个3元素到最前面。
所以快速排序是一个不稳定的排序算法,不稳定发生在中枢元素和a[j]交换的时刻。
*/
void Quick_Sort(int *array,int start,int end)
{
int middle;
if (start<end)
{
middle=partition(array,start,end);
Quick_Sort(array,start,middle-1);
Quick_Sort(array,middle+1,end);
}
}
void PrintArray(int *A,int len)
{
for (int i=1;i<=len;i++)
{
cout<<A[i]<<" ";
}
cout<<endl;
}
int main()
{
int len;
cin>>len;
int *A=new int[len+1];
int i;
for (i=1;i<=len;i++)
{
cin>>A[i];
}
//数组元素都是从1开始存
Insert_Sort(A,len);
Select_Sort(A,len);
Merge_Sort(A,1,len);
Bubble_Sort(A,len);
Quick_Sort(A,1,len);
PrintArray(A,len);
return 0;
}
选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、归并排序和基数排序是稳定的排序算法。