西北工业大学 程序设计大作业Word下载.docx
《西北工业大学 程序设计大作业Word下载.docx》由会员分享,可在线阅读,更多相关《西北工业大学 程序设计大作业Word下载.docx(19页珍藏版)》请在冰豆网上搜索。
根据堆排序的算法,最后输出
归并排序函数:
根据归并排序的算法,最后输出
基数排序函数:
根据基数排序的算法,最后输出
2.3函数实现
主函数:
在主函数中对菜单输出,通过switch语句中的case分支选择所需要的排序方法;
通过while循环使演示程序在运行时能够持续进行
快速排序:
快速排序(kuaisu)又被称做分区交换排序,这是一种平均性能非常好的排序方法。
其算法基本思想是:
任取排序表中的某个数据元素(例如取第一个数据元素)作为基准,按照该数据元素的关键字大小,将整个排序表划分为左右两个子表:
左侧子表中所有数据元素的关键字都小于基准数据元素的关键字。
右侧子表中所有数据元素的关键字都大于或等于基准数据元素的关键字,基准数据元素则排在这两个子表中间(这也是该数据元素最终应安放的位置),然后分别对这两个子表重复施行上述方法的快速排序,直到所有的子表长度为1,则排序结束。
插入排序:
插入排序(charu)的基本思想:
开始时把第一个数据元素作为初始的有序序列,然后从第二个数据元素开始依次把数据元素按关键字大小插入到已排序的部分排序表的适当位置。
当插入第i(1<
i<
=n)个数据元素时,前面的i-1个数据元素已经排好序,这时,用第i个数据元素的关键字与前面的i-1个数据元素的关键字顺序进行比较,找到插入位置后就将第i个数据元素插入。
如此进行n-1次插入,就完成了排序。
以下是在顺序表上实现的直接插入排序
在顺序表上进行直接插入排序时,当插入第i(1<
=n)个数据元素时,前面的A[0]、A[1]、…、A[i-2]已经排好序,这时,用A[i-1]的关键字依次与A[i-2],A[i-3],…的关键字顺序进行比较,如果这些数据元素的关键字大于A[i-1]的关键字,则将数据元素向后移一个位置,当找到插入位置后就将A[i-1]插入,就完成了A[0],A[1],…,A[n-1]的排序。
选择排序
选择排序(xuanze)的算法基本思想是:
a)开始时设i的初始值为0。
b)如果i<
n-1,在数据元素序列A[i](A[n-1]中,选出具有最小关键字的数据元素A[k];
否则算法结束。
c)若A[k]不是这组数据元素中的第一个数据元素(i≠k),则将A[k]与A[i]这两数据元素的位置对调;
d)令i=i+1转步骤b)。
冒泡排序:
冒泡排序(maopao)的基本思想是:
设排序表中有n个数据元素。
首先对排序表中第一,二个数据元素的关键字A[0]和A[1]进行比较。
如果前者大于后者,则进行交换;
然后对第二,三个数据做同样的处理;
重复此过程直到处理完最后两个相邻的数据元素。
我们称之为一趟冒泡,它将关键字最大的元素移到排序表的最后一个位置,其他数据元素一般也都向排序的最终位置移动。
然后进行第二趟排序,对排序表中前n-1个元素进行与上述同样的操作,其结果使整个排序表中关键字次大的数据元素被移到A[n-2]的位置。
如此最多做n-1趟冒泡就能把所有数据元素排好序。
堆排序:
堆排序(duipai)s
a.对排序表中的数据元素,利用堆的调整算法形成初始堆。
b.输出堆顶元素。
c.对剩余元素重新调整形成堆。
d.重复执行第b、c步,直到所有数据元素被输出。
如果建立的堆满足最大堆的条件,则堆的第一个数据元素A[0]具有最大的关键字,将A[0]与A[n-1]对调,把具有最大关键字的数据元素交换到最后,再对前面的n-1个数据元素使用堆的调整算法,重新建立最大堆,结果把具有次最大关键字的数据元素又上浮到堆顶,即A[0]的位置,再对调A[0]和A[n-2],…,如此反复执行n-1次,最后得到全部排序好的数据元素序列。
归并排序:
其基本思想是:
设有两个有序表A和B,其数据元素个数(表长)分别为n和m,变量i和j分别是表A和表B的当前检测指针;
设表C是归并后的新有序表,变量k是它的当前存放指针。
开始时i、j、k都分别指向A、B、C三个表的起始位置;
然后根据A[i]与B[j]的关键字的大小,把关键字小的数据元素放到新表C[k]中;
且相应的检测指针(i或j)和存放指针k增加1.如此循环,当i与j中有一个已经超出表长时,将另一个表中的剩余部分照抄到新表C[k]~C[m+n]中。
下面的归并算法中,两个待归并的有序表首尾相接存放在数组sourcetable.arr[]中,其中第一个表的下标范围从left到mid,另一个表的下标范围从mid+1到right。
前一个表中有mid-left+1个数据元素,后一个表中有right–mid个数据元素。
归并后得到的新有序表有right–mid个数据元素。
归并后得到的新有序表存放在另一个辅助数组mergedtable.arr[]中,其下标范围从left到right。
一趟归并算法:
设数组sourcetable.arr[0]到sourcetable.arr[n-1]中的n个数据元素已经分为一些长度为len的归并项,将这些归并项两两归并,归并成一些长度为2len的归并项,结果放到mergedtable.arr[]中。
如果n不是2len的整数倍,则一趟归并到最后,可能遇到两种情况:
剩下一个长度为len的归并项和一个长度不足len的归并项,可用一次merge算法,将它们归并成一个长度小于2len的归并项。
只剩下一个归并项,其长度小于或等于len,可将它直接复制到数组mergedtable.arr[]中。
在一趟归并算法的基础上,实现两路归并排序算法。
在两路归并排序算法中,初始排序表存放在数组table.arr[]中,第一趟归并将table.arr[]中的归并项两两归并,结果存放在辅助数组temptable.arr[]中。
第二趟将temptable.arr[]中的归并项两两归并,结果放回原数组table.arr[]中,如此反复进行。
为了将最后归并结果仍放在数组table.arr[]中,归并趟数应为偶数。
如果做奇数趟就能完成时,最后还需要执行一次一趟归并过程,由于这时的归并项长度len>
=n,因此在则趟归并中while循环不执行,只做把temptable.arr[]中的数据元素复制到table.arr[]的工作。
基数排序:
“基数排序法”(radixsort)则是属于“分配式排序”(distributionsort),基数排序法又称“桶子法”(bucketsort)或binsort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O(nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的比较性排序法。
具体可以参看后面的代码进行理解。
其它:
使用了stdlib头文件里包含的系统函数,包括清屏函数和运行时的暂停,增强了程序运行时的效果。
2.4开发日志
在老师布置了大作业的题目后,我就把题目下载下来并进行分析已选择合适的题目。
经过我的慎重考虑,选择了算法型大作业题目中的编写七种排序算法的演示程序,觉得自己有能力把这道题目很好完成。
在认真分析连题目后,基本确定了整体的思路,但是其中有堆排序,归并排序,基数排序我没有在教材中接触过,于是借助了图书馆和网络上的资源,重点对这三的函数进行编写。
在编写大作业过程中大的困难我没有遇到,只是有些小的疏忽常常导致程序无法运行,如形参和实参的不一致等。
我也在其中意识到对知识掌握的不够熟练,在解决了这些问题后,我觉得自己对程序的编写更加熟练了,对问题的分析也更加严谨了。
在C程序设计的实验和理论考试之前代码已基本完成。
在考试结束后,我又对程序稍微进行了修改,使之运行时效果更好。
接着开始写实验报告,整理自己的大作业。
我对我的作业是很满意的。
3程序调试及运行
3.1程序运行结果
1.进入程序运行后所显示的菜单:
2.快速排序:
3.插入排序:
4.选择排序:
5.冒泡排序:
6.堆排序:
7.归并排序:
8.基数排序:
9.结束:
3.2程序使用说明
1.打开源程序,调试完毕后开始运行,开始进行七种算法的演示;
2.按照说明进行输入,选择数字1~7即可进入相应的排序算法演示程序,选择8结束程序;
3.选择排序的方法后,按要求输入待排数据的个数,然后输入待排序数据即可(数据排序结束后,会自动清屏,进入菜单进行接下来的选择);
4.应当注意,本演示程序对数据进行的是升序;
3.3程序开发总结
在选择这个题目时,我觉得难度系数10对我有挑战性,并且我对排序有相对比较熟悉,所以就选了这个题目。
但是在编写过程中却遇到很多问题。
我和我的同学进行了讨论,查阅了图书馆和网络上的资料,结合力我个人对本题目的理解对各种问题进行了处理,学到了很多教材上没有的知识。
从这次实践中,我意识到自己还有很多不足之处。
能力也得到了提高。
我在进行编程时还需要翻书查找,对于这一点,只能说对知识的学习还不够扎实,所以有空时还应该继续熟悉这门课程。
另外,就是对于错误的处理,不能得心应手,不能正确处理一些简单的错误。
对于逻辑上的错误,不能够立即找到出错点,往往需要向同学请教才能找出错误,并且改正。
我觉得这是自己独自思考能力不高的问题,遇事需要自己仔细想想,若还不能改正,再请教别人也不迟。
从总体上说,最终结果我很满意,我觉得我所设计的程序操作方便,功能良好。
我在上面花费了很多时间和精力,对作业不断进行修改和完善,我很有成就感。
我的能力在这之中得到了提高。
4附件(源程序)
#include<
stdio.h>
stdlib.h>
////////////////////**********快速排序**********//////////////////////
voidkuaisu(intA[],intn)
{
inti,j,k,t,p;
for(i=0;
n-1;
i++)
{
k=i;
for(j=i+1;
j<
n;
j++)
if(A[j]<
A[k])k=j;
t=A[k];
A[k]=A[i];
A[i]=t;
printf("
第%d趟:
"
i+1);
for(p=0;
p<
p++)
printf("
%d"
A[p]);
}
\n"
);
\n排序结果:
A[i]);
system("
pause"
CLS"
}
////////////////////**********插入排序**********//////////////////////
voidcharu(intA[],intn)
{
inti,k,t,j,h=1;
for(i=1;
t=A[i];
k=i-1;
while(t<
A[k])
{
A[k+1]=A[k];
k--;
if(k==-1)break;
printf("
h++);
for(j=0;
printf("
A[j]);
}
A[k+1]=t;
////////////////////**********选择排序**********//////////////////////
voidxuanze(intA[],intn)
inti,j,k,t,l,h=1;
k=i;
for(j=i+1;
if(A[j]<
if(i!
=k)
t=A[i];
A[i]=A[k];
A[k]=t;
for(l=0;
l<
l++)
A[l]);
};
////////////////////**********冒泡排序**********//////////////////////
voidmaopao(intA[],intn)
inti,j,t,h=1,p;
for(j=0;
for(i=0;
n-1-j;
if(A[i]>
A[i+1])
t=A[i],A[i]=A[i+1],A[i+1]=t,p++;
for(p=0;
/////////////////////**********堆排序**********///////////////////////
voidshift(intA[],inti,intm)
intk,t;
t=A[i];
k=2*i+1;
while(k<
m)
if((k<
m-1)&
&
(A[k]<
A[k+1]))k++;
if(t<
A[k]){A[i]=A[k];
i=k;
elsebreak;
voidduipai(intA[],intn)//a为排序数组,n为数组大小
inti,k,h=1,j;
for(i=n/2-1;
i>
=0;
i--)shift(A,i,n);
for(i=n-1;
=1;
i--)
k=A[0];
A[0]=A[i];
A[i]=k;
shift(A,0,i);
////////////////////**********归并排序**********//////////////////////
voidmerge(intnumber[],intfirst,intlast,intmid)
intnumber_temp[10]={0};
inti=first,j=mid+1,k;
for(k=0;
k<
=last-first;
k++)
if(i==mid+1)
number_temp[k]=number[j++];
continue;
if(j==last+1)
number_temp[k]=number[i++];
if(number[i]<
number[j])number_temp[k]=number[i++];
elsenumber_temp[k]=number[j++];
for(i=first,j=0;
=last;
i++,j++)
number[i]=number_temp[j];
voidmerge_sort(intnumber[],intfirst,intlast)
intmid=0;
if(first<
last)
mid=(first+last)/2;
merge_sort(number,first,mid);
merge_sort(number,mid+1,last);
merge(number,first,last,mid);
voidguibing(inta[],intn)
inti;
merge_sort(a,0,n-1);
a[i]);
}
////////////////////**********基数排序**********//////////////////////
voidjishu(intdata[],intn)
inttemp[10][10]={0};
intorder[10]={0};
inti,j,k,q,lsd;
k=0;
q=1;
while(q<
=n)
{
lsd=((data[i]/q)%n);
temp[lsd][order[lsd]]=data[i];
order[lsd]++;
}
i++)
if(order[i]!
=0)
order[i];
{
data[k]=temp[i][j];
k++;
order[i]=0;
q*=n;
k=0;
data[i]);
system("
////////////////////***********主函数***********//////////////////////
intmain()
intA[100],p,n,i;
while
(1)
{
\n\t****************七种排序算法的演示程序***************\n"
\t**\n"
\t*1-----快速排序*\n"
\t*2-----插入排序*\n"
\t*3-----选择排序*\n"
\t*4-----冒泡排序*\n"
\t*5-----堆排序*\n"
\t*6-----归并排序*\n"
\t*7-----基数排序*\n"
\t*8-----退出程序*\n"
\t*********************************************************\n\n"
请输入序号进行选择:
scanf("
%d"
&
p);
if(p==8)break;
请输入待排序数的个数:
n);
请输入待排序数据:
scanf("
A[i]);
switch(p)
case1:
kuaisu(A,n);
break;
case2:
charu(A,n);
case3:
xuanze(A,n);
case4:
maopao(A,n);
case5:
duipai(A,n);
case6:
guibing(A,n);
case7:
jishu(A,n);
\n\n\t\t\t\t谢谢您的使用\n\n"
return0;