(1)直接插入
算法的复杂度O(n * n)。
头文件:
#defineMAXSIZE20
#defineEQ(a,b)((a)==(b))
#defineLT(a,b)((a)<(b))
#defineLQ(a,b)((a)<=(b))
typedefintKeyType;
typedefintInfoType;

typedefstruct...{
KeyTypekey;
InfoTypeotherinfo;
}RedType;

typedefstruct...{
//r[0]isthesentinel,notused.
RedTyper[MAXSIZE+1];
intlength;
}SqList;
源文件:
#include"stdio.h"
#include"sort.h"

voidinit(SqList&s,intw[],intn)...{
s.length=n;
for(inti=1;i<=n;i++)...{
s.r[i].key=w[i-1];
}
}

voidshow(SqLists)...{
for(inti=1;i<=s.length;i++)...{
printf("%d ",s.r[i]);
}
printf(" ");
}

voidinsert(SqList&s)...{
for(inti=2;i<=s.length;i++)...{
if(LT(s.r[i].key,s.r[i-1].key))...{
//setthesentinel
s.r[0]=s.r[i];
s.r[i]=s.r[i-1];
for(intj=i-2;LT(s.r[0].key,s.r[j].key);j--)...{
s.r[j+1]=s.r[j];
}
s.r[j+1]=s.r[0];
}
}
}

voidmain()...{
intw[]=...{49,38,65,97,76,13,27,49};
intn=8;
SqLists;
init(s,w,n);
insert(s);
show(s);
}
执行结果:
1327384949657697
Pressanykeytocontinue
(2)减少比较次数-折半插入
源文件添加:
//usethebinarysearchmethodtofindthelocationtoinsert.
voidbinaryInsert(SqList&s)...{
for(inti=2;i<=s.length;i++)...{
//setthesentinel
s.r[0]=s.r[i];
//binarysearchthelocationtoinsert
intlow=1,high=i-1;
intm;
while(low<=high)...{
m=(low+high)/2;
if(LT(s.r[0].key,s.r[m].key))...{
high=m-1;
}else...{
low=m+1;
}
}

for(intj=i-1;j>=high+1;j--)...{
s.r[j+1]=s.r[j];
}
s.r[high+1]=s.r[0];
}
}
折半插入仅减少了比较次数,而记录的移动次数没变。
(3)减少移动次数-表插入排序
头文件:
#defineSIZE100
#defineEQ(a,b)((a)==(b))
#defineLT(a,b)((a)<(b))
#defineLQ(a,b)((a)<=(b))
typedefintKeyType;
typedefintInfoType;

typedefstruct...{
KeyTypekey;
InfoTypeotherinfo;
}RedType;

typedefstruct...{
RedTyperc;
intnext;
}SLNode;

typedefstruct...{
//r[0]isheadofstaticlist
SLNoder[SIZE];
intlength;
}SLinkListType;
源文件:
#include"stdio.h"
#include"SLLInsert.h"

voidinit(SLinkListType&s,intw[],intn)...{
s.length=n;
for(inti=1;i<=n;i++)...{
s.r[i].rc.key=w[i-1];
//pointtothehead,touser[o]asasentinal
s.r[i].next=0;
}
s.r[0].next=1;
}

voidshow(SLinkListTypes)...{
for(inti=0;i<=s.length;i++)...{
printf("%d:%d(%d) ",i,s.r[i].rc.key,s.r[i].next);
}
printf(" ");
}

voidinsert(SLinkListType&s)...{
intparent,next;

for(inti=2;i<=s.length;i++)...{
s.r[0].rc.key=s.r[i].rc.key;
parent=0;
next=s.r[parent].next;

while(LT(s.r[next].rc.key,s.r[0].rc.key))...{
parent=next;
next=s.r[next].next;
}
//insert
s.r[i].next=next;
s.r[parent].next=i;
}
}

voidmain()...{
intw[]=...{49,38,65,97,76,13,27,49};
intn=8;
SLinkListTypes;
init(s,w,n);
insert(s);
show(s);
}
程序执行结果:
0:49(6)1:49(3)2:38(8)3:65(5)4:97(0)
5:76(4)6:13(7)7:27(2)8:49(1)
Pressanykeytocontinue
表插入并没有减少比较次数,故复杂度仍为O(n * n)。
(4)shell排序
子序列的构成不是简单的“逐段分割”,而是将相隔某个“增量”的记录组成一个子序列。
源文件添加:
//onepassofshellsort
voidshellInsert(SqList&s,intdk)...{
intj;
for(inti=dk+1;i<=s.length;i++)...{
if(LT(s.r[i].key,s.r[i-dk].key))...{
s.r[0]=s.r[i];
for(j=i-dk;j>0&<(s.r[0].key,s.r[j].key);j-=dk)...{
s.r[j+dk]=s.r[j];
}
s.r[j+dk]=s.r[0];
}
}
}

voidshellSort(SqList&s,intdlta[],intt)...{
for(intk=0;k<t;k++)...{
shellInsert(s,dlta[k]);
}
}

voidmain()...{
intw[]=...{49,38,65,97,76,13,27,49};
intn=8;

intdlta[]=...{5,3,1};
intt=3;
SqLists;
init(s,w,n);
//binaryInsert(s);
shellSort(s,dlta,t);
show(s);
}
程序执行结果:
1327384949657697
Pressanykeytocontinue
注意:增量序列中 dlta[] 没有除了1以外的公因子,并且最后一个增量值必须等于1。

被折叠的 条评论
为什么被折叠?



