a[j+1].key=a[j].key;
a[j+1]=next;
}
printf("输出直接插入排序的结果:
\n");
}
/////////////////希尔排序//////////////////////
voidshell(structelementa[SIZE],intn)
{
inti,j,k;
for(i=n;i>=1;i--)
a[i].key=a[i-1].key;
k=n/2;
while(k>=1)
{
for(i=k+1;i<=n;i++)
{
a[0].key=a[i].key;
j=i-k;
while((a[j].key>a[0].key)&&(j>=0))
{
a[j+k].key=a[j].key;
j=j-k;
}
a[j+k]=a[0];
}
k=k/2;
}
for(i=0;ia[i].key=a[i+1].key;
printf("输出希尔排序的结果:
\n");
}
////////////////////快速排序///////////////////////////
inthoare(structelementa[SIZE],intl,inth)//分区处理函数
{
inti,j;
structelementx;
i=l;
j=h;
x.key=a[i].key;
do
{
while((i=x.key))
j--;
if(i{
a[i].key=a[j].key;
i++;
}
while((ii++;
if(i{
a[j].key=a[i].key;
j--;
}
}while(ia[i].key=x.key;
return(i);
}
voidquick1(structelementa[SIZE],intn)//非递归的快速排序
{
inti,l,h,tag,top;
ints[20][2];
l=0;h=n-1;tag=1;top=0;
do
{
while(l{
i=hoare(a,l,h);
top++;
s[top][0]=i+1;
s[top][1]=h;
h=h-1;
}
if(top==0)
tag=0;
else
{
l=s[top][0];
h=s[top][1];
top--;
}
}while(tag==1);
}
voidquick2(structelementa[SIZE],intl,inth)//递归的快速排序
{
inti;
if(l{
i=hoare(a,l,h);//划为两个区
quick2(a,l,i-1);//对左分区快速排序
quick2(a,i+1,h);//对右分区快速排序
}
}
////////////////////堆排序函数//////////////////////////
//调整堆的函数
voidheap(structelementa[SIZE],inti,intm)
/*i是根结点编号,m是以i为根的子树的最后一个结点编号*/
{
structelementx;
intj;
x.key=a[i].key;//保存记录内容
j=2*i;//j为左孩子编号
while(j<=m)
{
if(jif(a[j].key>a[j+1].key)//当结点i有左,右两个孩子时,j取关键较小的孩子编号
j++;
if(a[j].key{
a[i].key=a[j].key;
i=j;
j=2*i;
}
else
j=m+1;//x.key小于左,右孩子的关键字时,使j>m,以便结束循环
}
a[i].key=x.key;
}
//堆排序的主体函数
voidheapsort(structelementa[SIZE],intn)
{
inti,v;
structelementx;
for(i=n;i>0;i--)
a[i].key=a[i-1].key;
for(i=n/2;i>=1;i--)
heap(a,i,n);
for(v=n;v>=2;v--)
{
x.key=a[1].key;//堆顶堆尾元素交换
a[1].key=a[v].key;
a[v].key=x.key;
heap(a,1,v-1);//这次比上次少处理一个记录
}
for(i=0;ia[i].key=a[i+1].key;
for(i=0;iintk;
k=a[i].key;
a[i].key=a[n-i-1].key;
a[n-i-1].key=k;
}
}
voidmain()
{
intnum,l,h,c;
clock_tstart,end;
c=1;
charfile1[50]="直接插入排序.txt";
charfile2[50]="希尔排序.txt";
charfile3[50]="非递归的快速排序.txt";
charfile4[50]="递归的快速排序.txt";
charfile5[50]="堆排序.txt";
printf("***********欢迎使用本系统学习各种排序*************\n");
printf("*温馨提示:
首先请生成用于排序的元素,以便进行排序*\n");
printf("********************主菜单************************\n");
printf("*1生成随机排序元素*\n");
printf("*2直接插入排序*\n");
printf("*3希尔排序*\n");
printf("*4非递归的快速排序*\n");
printf("*5递归的快速排序*\n");
printf("*6堆排序*\n");
printf("*0退出*\n");
printf("**************************************************\n");
while(c!
=0)
{
printf("*请输入0-6进行操作\n");
scanf("%d",&c);
switch(c)
{
case1:
num=creat();
print(list,num);
break;
case2:
start=clock();
insert_sort(list,num);
end=clock();
print(list,num);
save(list,num,file1);
printf("Thetime:
%dms\n",end-start);
break;
case3:
start=clock();
shell(list,num);
end=clock();
print(list,num);
save(list,num,file2);
printf("Thetime:
%dms\n",end-start);
break;
case4:
start=clock();
quick1(list,num);
end=clock();
print(list,num);
save(list,num,file3);
printf("Thetime:
%dms\n",end-start);
break;
case5:
l=0;h=num-1;
start=clock();
quick2(list,l,h);
end=clock();
printf("输出递归快速排序结果:
\n");
print(list,num);
save(list,num,file4);
printf("Thetime:
%dms\n",end-start);
break;
case6:
start=clock();
heapsort(list,num);
end=clock();
print(list,num);
save(list,num,file5);
printf("Thetime:
%dms\n",end-start);
break;
}
}
}//mainend
4、调试分析
4.1、insertion_sort排序算法分析:
该算法的时间复杂度为O(n*n).直接插入排序是稳定的排序方法。
当n值较小时,n和n2的差别也较小,即直接插入排序的最好时间复杂度O(n)和最坏时间复杂度0(n2)差别不大。
4.2、shell排序算法分析:
Shell排序算法的时间复杂度分析比较复杂,实际所需的时间取决于各次排序时增量的个数和增量的取值。
当n较大时,比较和移动的次数约在nl.25到1.6n1.25之间。
由于Shell排序算法是按增量分组进行的排序,所以Shell排序算法是一种不稳定的排序算法。
4.3、quick排序算法分析:
快速排序主体算法时间运算约为O(log2n),划分子区函数运算量约为O(n),所总时复杂度为O(nlog2n).因为快速排序的记录移动次数不大于比较的次数,所以快速排序的最坏时间复杂度应为0(n2),最好时间复杂度为O(nlgn)。
4.4、heapsort排序算法分析:
堆排序中heap算法的时间复杂度与堆所对应的完全二叉树的深度[log2n]+1相关,而heapsort中对heap的调用数量级为n,所以整个堆排序的时间复杂度为O(nlog2n)。
堆排序是不稳定的。
5、调试结果
5.1系统操作
5.1.1、主菜单界面
5.1.2、生成排序元素
5.1.3直接插入排序
5.1.4、希尔排序
5.1.5非递归的快速排序
5.1.6递归的快速排序
5.1.7堆排序
5.2、测试数据
5.2.1、100个数据元素
5.2.2、1000个数据元素
5.2.3、10000个数据元素
5.2.4、100000个数据元素
课程设计总结
通过这次课程设计的学习让我学会了许多。
让我对我们的专业知识有了很大理解!
我对专业的课程有了初步的认识。
在这次课程设计中,独立完成了在两种存储结构下的每种排序算法。
排序算法共有七个:
插入排序、希尔排序、冒泡排序、快速排序、选择排序、堆排序、归并排序。
同时也实现了随机数的生成。
并把排序后的结果保存在不同的文件中。
虽然在算法完成的过程中也在网上查阅了一些资料,但对这次课程设计的成果还是非常满意的。
这次的课程设计还有很多不足之处,如链表存储结构中的堆排序算法,当排序个数过多时,就会等待很长时间。
可能时调用的函数过多的原因造成的,但排序是正确的。
用指针代替函数的调用。
还有就是随机数不能随时更改,只能设定一次。
链表归并算法不是对链表直接操作,而是将链表中的元素放入数组中进行排序,我想了很多方法都没有想出对链表的直接操作的算法。
由于时间限制,只在课程设计快结束时完成了产生随机文件这部分,我想以后有时间再来完成它。
同时在完成这个课程设计后,我也学到了很多知识,并能训练的掌握他们了。
首先学会了随机数的产生。
熟练的撑握了C语言的文件读写操作。
撑握了每种排序算法的基本思想,并从同学那里学会了编写程序的一般步骤:
思考问题,写出解决方案,写出伪代码,完成代码,调试程序。
不像以前那样开始就直接写代码。
但我还是认为自己有些不足,希望以后能弥补这些不足。
所以,这次的课程设计我学会了很多,不光让我认识了本专业知识,还让我学了一定的心境!
那就是做事情的时候即使不会做也不能慌张,要慢慢放下心来,不要光想自己怎么、怎么不会了!
不要去想不会,而是冷下心来慢慢思考、思考。
这样你就会有了思虑的。