1.冒泡排序法
void bubble_sort(int data[])
{
for(int i=n-1;i>=0;--i)
{
int flag=0;
for(int j=0;j<i;++j)
{
if(data[j+1]<data[j])
{
int tmp;
tmp=data[j];
data[j]=data[j+1];
data[j+1]=tmp;
flag++;
}
if(flag==0)
break;
}
}
}
分析:
冒泡排序法最坏情况及平均情况均需要比较(n-1)+(n-2)+...+3+2+1=n*(n-1)/2次,时间复杂度为O(n^2),最好的情况只需要扫描一次,发现没有交换的动作则表示已经排序完成,所以只做了n-1次比较,时间复杂度为O(n).
由于冒泡排序为相邻两者相互比较并对调,不会影响其他元素的顺序,所以是稳定排序法
只需要一个额外的空间,适用于数据量小或者有部分数据已经排过序的数组
2.选择排序法
void select_sort(int data[])
{
for(int i=0;i<n-1;++i)
{
for(int j=i+1;j<n;++j)
{
if(data[i]>data[j])
{
swap(data[i],data[j]);
}
}
}
}
分析:
无论是最坏情况、最好情况还是平均情况都需要找到最大值(或最小值),所以比较次数为(n-1)+(n-2)+...+3+2+1=n*(n-1)/2,时间复杂度为O(n^2)。
由于选择排序是以最大值或最小值直接与最前方未排序的键值交换,数据排列顺序有可能被改变,不是稳定排序法
只需要一个额外空间,适用于数据量小或有部分数据已经排过序的数组
3.插入排序法
void insert_sort(int data[])
{
int i;
int j;
for(i=1;i<n;++i)
{
int tmp;
tmp=data[i];
j=i-1;
while(j>=0&&tmp<data[j])
{
data[j+1]=data[j];
j--
}
data[j+1]=tmp;
}
}
分析:
最坏及平均情况都需要比较(n-1)+(n-2)+...+3+2+1=n*(n-1)/2次,
是稳定排序法,只需要一个额外空间,适用于大部分数据已经排过序或已排序数组新增数据后进行排序
会造成大量数据移动,建议在链表结构使用
4.桶排序法(基数排序法)
不需要进行元素间的比较操作,属于分配排序方式,包括最高位优先、最低位优先(按照个位数、十位数、百位数。。的顺序进行排序)
分析:
在所有情况下,时间复杂度均为O(nlogp(k)),k为原始数据的最大值,p是数据位数
桶排序法(基数排序法)是稳定排序法
基数排序法会使用到很大的额外空间来存放序列数据,其空间复杂度为O(n*p),其中n是原始数据的个数,p是数据位数
若n很大,p固定或很小时,效率较高
5.希尔排序法
类似于插入排序法,但可以减少数据移动的次数,排序的原则是将数据划分成特定间隔的几个子集,以插入排序法排完子集内的数据后再逐渐减少间隔的距离。
分析:
任何情况下的时间复杂度均为O(n^(3/2))
希尔排序法和插入排序法一样都是稳定排序法
只需要一个额外空间,空间复杂度最佳
适用于数据大部分已经排序完成的情况
6.快速排序法
7.堆排序法