直接插入排序
每次将一个待排序的记录按其关键字大小插入到前面已经排好的子序列中,直到全部记录插入完成
以下面的例子为准。第一趟的时候是第一个元素和自己比,所以第一趟不变。第二趟是前两个元素进行排序,所以38 和49互换位置,后面的元素不动,第三趟是前三个元素进行排序,所以是38,49,65 以此类推。
因为第一趟是只有第一个元素和自己进行比较排序,所以我在待排序序列中 49下面画了个三角
形,第一趟顺序不变。第二趟是要看前两个元素的排序,所以我在第一趟的前两个元素下面画了横线,根据这两个元素来写出第二趟的排序顺序。
算法思想: 使用监视哨兵A[0]临时保存待插入的记录,从后往前找应插入的位置,查找与移动用 同一循环完成。
代码实现
void InsertSort (int A[], int n){
int i,j;
for(i=2;i<=n;i++)
{
A[0]=A[i]; //将待插入记录存放在监视哨兵A[0]中
j=i-1;
while(A[0].key<A[j].key){ //寻找插入位置
A[j+1]=A[j];
j=j-1;
}
A[j+1]=A[0]; //将待插入记录插入到已排序的序列中
}
}
空间复杂度O(1)
时间复杂度O(n²)
稳定性:稳定
适用于待排序记录数目较少且基本有序的情况。
折半插入排序
对有序表进行折半查找,其性能优于顺序查找。所以,可以将折半查找思想用于有序记录中,确定插入位置,相应的排序法称为折半插入排序。
void BinSort (RT r[],int length)
{
for(i=2;i<=length;++i)
{
x=r[i];
low=1; high=i-1;
while(low<=high) //确认插入位置
{
mid=(low+high)/2;
if(x.key<r[mid].key)
high=mid-1; //查找左半子表
else
low=mid+1; //查找右半子表
}
for(j=i-1;j>=low;--j) //记录依次向后移
r[j+1]=r[j];
r[low]=x; //插入位置
}
}
空间复杂度O(1)
时间复杂度O(n²)
稳定性:稳定
当n较大时,折半插入法的比较次数比直接插入排序的最差情况要好很多,
比直接插入排序的最好情况要查
希尔排序
先将待排序表分割成若干形如L【i,i+d,i+2d,,,,i+kd】的特殊子表,对各个子表分别进行直接插入排序,缩小增量d,重复上述过程,直到d=1为止。
void ShellSort(int A[],int n){
int i,j,d;
for(d=n/2;d>=1;d=d/2)
for(i=d+1;i<=n;i++)
if(A[i]<A[i-d]){
A[0]=A[i];
for(j=i-d;j>0&&A[0]<A[j];j-=d)
A[j+d]=A[j];
A[j+d]=A[0];
}
}
空间复杂度O(1)
时间复杂度O(n的1.5次方)
适用于线性表为顺序存储的情况。
对于中等规模(n≤1000)的序列具有较高的效率,且希尔排序算法简单,容易执行。
稳定性:不稳定
冒泡排序
从后往前或从前往后两两比较相邻元素的值。
void Bubble (ElemType A[],int n){
for(i=0;i<n-1;i++)
{
flag=false;
for(j=n-1;j>1;j--)
{
if(A[j-1]>A[j]){
swap(A[j-1],A[j]);
flag=true;
}
if(flag==false)
return;
}
}
空间复杂度O(1)
时间复杂度O(n²)
稳定性:稳定
快速排序
在待排序表中任取一个元素作为枢轴,通常为第一个元素。一趟快排或一次划分后在枢轴的左边都小于等于枢轴元素,相反,右边的都是大于。
int Part (ElemType r[],int low,int high){
x=r[low]; //选择基准记录
while(low<high)
{
while(low<high && r[high].key>=x.key)
high--;
if(low<high)
{
r[low]=r[high]; //找到小于x.key的记录,送入空单元r[low]
low++;
}
while(low<high && r[low].key<x.key)
low++;
if(low<high)
{
r[high]=r[low]; //找到大于等于x.key的记录,送入空单元r[high]
high--;
}
}
r[low]=x;
return low;
}
时间复杂度O(n²)
稳定性:不稳定
简单选择排序
每一趟在n-i+1 个记录中选择关键字最小的记录作为有序序列中第i个记录。
void Select( RT r[],int n)
{
for(i=1;i<n;i++)
{
k=i;
for(j=i+1;j<=n;++j)
if(r[j].key<r[k].key)
k=j;
if(k!=i)
{
x=r[i];
r[i]=r[k];
r[k]=x;
}
}
}
空间复杂度O(1)
时间复杂度O(n²)
稳定性:不稳定