1.直接插入排序
每次将一个数据插入到已排序好的有序表中,从而每次得到一个新的,记录数增1的有序表,最后形成整个表有序,时间复杂度为O(n^2)。
//直接插入排序;
void Direct_Insert_Sort(int *my_list)
{
int i,j;
for(i=2;i<=length;i++)
{
if(my_list[i]<my_list[i-1])//若当前键值已经大于排好部分的最大键值,则该键值不用插入;
{
my_list[0]=my_list[i];
my_list[i]=my_list[i-1];//移动位置;
for(j=i-2;my_list[0]<my_list[j];j--)
{
my_list[j+1]=my_list[j];
}
my_list[j+1]=my_list[0];
}
}
}
2.折半插入排序
即在有序部分进行折半查找要插入的位置,但其仅改变了关键字的比较次数,记录移动次数并不变,故时间复杂度仍为O(n^2)。
//折半插入排序
void Binary_Insert_Sort(int *my_list)
{
int i,j;
int low,high;
for(i=2;i<=length;i++)
{
my_list[0]=my_list[i];
low=1;
high=i-1;//确定二分界限;
while(low<=high)
{
int mid=(low+high)/2;
if(my_list[0]<my_list[mid])
{
high=mid-1;
}
else
{
low=mid+1;
}
}
for(j=i-1;j>=high+1;j--)
{
my_list[j+1]=my_list[j];
}
my_list[high+1]=my_list[0];
}
}
3.希尔排序
先将整个待排序序列分割成若干个子序列分别进行直接插入排序,待整个序列基本有序,再进行一次直接插入排序。一般增量序列为素数较好,且最后一个增量一定要为1。
//希尔排序;
int dk_test[5]={11,7,5,3,1};//增量数组((除1外最好为素数),最后一个增量必须为1);
int len=5;//增量序列的长度;
void Shell_Insert(int *my_list,int dk)
{
int i,j;
for(i=dk+1;i<=length;i++)
{
//即对增量构成的子序列进行直接插入排序;
if(my_list[i]<my_list[i-dk])
{
my_list[0]=my_list[i];
for(j=i-dk; j>=1&&my_list[0]<my_list[j]; j-=dk)
{
my_list[j+dk]=my_list[j];
}
my_list[j+dk]=my_list[0];
}
}
}
void Shell_Sort(int *my_list,int dk_test[],int len)
{
for(int i=0;i<len;i++)
{
Shell_Insert(my_list,dk_test[i]);
}
}
三个算法的测试代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAXSIZE 20
typedef int KeyType;//以整数类型为例;
int my_list[MAXSIZE];
int length;
//举例均默认排序为递增数组;
//直接插入排序;
void Direct_Insert_Sort(int *my_list)
{
int i,j;
for(i=2;i<=length;i++)
{
if(my_list[i]<my_list[i-1])//若当前键值已经大于排好部分的最大键值,则该键值不用插入;
{
my_list[0]=my_list[i];
my_list[i]=my_list[i-1];//移动位置;
for(j=i-2;my_list[0]<my_list[j];j--)
{
my_list[j+1]=my_list[j];
}
my_list[j+1]=my_list[0];
}
}
}
//折半插入排序
void Binary_Insert_Sort(int *my_list)
{
int i,j;
int low,high;
for(i=2;i<=length;i++)
{
my_list[0]=my_list[i];
low=1;
high=i-1;//确定二分界限;
while(low<=high)
{
int mid=(low+high)/2;
if(my_list[0]<my_list[mid])
{
high=mid-1;
}
else
{
low=mid+1;
}
}
for(j=i-1;j>=high+1;j--)
{
my_list[j+1]=my_list[j];
}
my_list[high+1]=my_list[0];
}
}
//希尔排序;
int dk_test[5]={11,7,5,3,1};//增量数组((除1外最好为素数),最后一个增量必须为1);
int len=5;//增量序列的长度;
void Shell_Insert(int *my_list,int dk)
{
int i,j;
for(i=dk+1;i<=length;i++)
{
//即对增量构成的子序列进行直接插入排序;
if(my_list[i]<my_list[i-dk])
{
my_list[0]=my_list[i];
for(j=i-dk; j>=1&&my_list[0]<my_list[j]; j-=dk)
{
my_list[j+dk]=my_list[j];
}
my_list[j+dk]=my_list[0];
}
}
}
void Shell_Sort(int *my_list,int dk_test[],int len)
{
for(int i=0;i<len;i++)
{
Shell_Insert(my_list,dk_test[i]);
}
}
int main()
{
int i,j;
int n,m;
length=5;
int order1[6]={0,1,3,5,4,2};//0位单元不用;
printf("原序列为:");
for(i=1;i<=5;i++)
{
printf("%d ",order1[i]);
}
printf("\n");
//test1:直接插入排序;
Direct_Insert_Sort(order1);
printf("直接插入排序后得到的序列:");
for(i=1;i<=5;i++)
{
printf("%d ",order1[i]);
}
printf("\n");
//test2:折半插入排序;
int order2[6]={0,1,3,5,4,2};
Binary_Insert_Sort(order2);
printf("折半插入排序后得到的序列:");
for(i=1;i<=5;i++)
{
printf("%d ",order2[i]);
}
printf("\n");
//test3:希尔排序;
int order3[6]={0,1,3,5,4,2};
Shell_Sort(order3,dk_test,len);
printf("希尔排序后得到的序列:");
for(i=1;i<=5;i++)
{
printf("%d ",order3[i]);
}
printf("\n");
return 0;
}