数据结构课程设计内部排序算法的比较Word文件下载.docx
- 文档编号:17859859
- 上传时间:2022-12-11
- 格式:DOCX
- 页数:14
- 大小:30.86KB
数据结构课程设计内部排序算法的比较Word文件下载.docx
《数据结构课程设计内部排序算法的比较Word文件下载.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计内部排序算法的比较Word文件下载.docx(14页珍藏版)》请在冰豆网上搜索。
进行希尔排序,返回排序后的顺序表
HeapSort(&
进行堆排序,返回排序后的顺序表
SelectSortMethod(&
L,c1)
打印提示信息,请用户选择排序方法,起泡排序、插入
排序、选择排序、快速排序、希尔排序还是堆排序
OutPut(L)
打印排序中关键字的比较次数和移动次数
}ADTOrderableList
2.本程序包含两个模块:
1).主程序模块
intmian()
{
初始化;
用户选择待测表的类型;
输入选择,用switch语句判断;
While(“命令”!
=“退出”)
{
接受命令;
处理命令;
}
}
2).可排序表单元模块----实现可排序表的抽象数据类型
各模块之间的调用关系:
主程序模块
可排序表单元模块
三、详细设计
1.根据题目要求何可排序表的基本操作特点,可排序表采用证书顺序表存储结构,并实现在头文件SqList.H。
//******************基本操作的函数原型******************\\
#defineMAXSIZE20//用作示例的顺序表的最大长度
typedefintKeyType;
//定义关键字为整数类型
typedefintInfoType;
//定义其他数据项也为整数类型
inttime_key_compare=0;
//定义全局变量,关键字比较次
inttime_key_move=0;
//数和移动次数均为0
typedefstruct
KeyTypekey;
//关键字项
InfoTypeotherinfo;
//其他数据项
}RedType;
//记录类型
RedTyper[MAXSIZE+1];
//r[0]闲置或用做哨兵
intlength;
//顺序表长度
}SqList;
//顺序表类型
//****************************基本操作*********************\\
boolLT(KeyTypea,KeyTypeb)//比较两个KeyType类型变量的大小
{
time_key_compare++;
//比较次数+1
if(a<
b)
returntrue;
//<
返回true
else
returnfalse;
//否则,返回false
}//LT
voidcopyKey(RedType&
a,RedType&
b)
{//将RedType类型变量b复制给a
a=b;
time_key_move++;
//关键字移动次数+1
}//copyKey
voidswap(RedType&
{//将RedType型变量a和b进行交换操作
RedTypec;
//定义RedType型变量c
c=a;
a=b;
b=c;
time_key_move+=3;
//关键字移动次数+3
}//swap
/****************直接插入排序*********************\
voidInsertSort(SqList&
{//对顺序表L做直接插入排序
for(inti=2;
i<
=L.length;
++i)
if(LT(L.r[i].key,L.r[i-1].key))
{//“<
”,需将L.r[i]插入有序子表
copyKey(L.r[0],L.r[i]);
//复制为哨兵
copyKey(L.r[i],L.r[i-1]);
for(intj=i-2;
LT(L.r[0].key,L.r[j].key);
--j)
{
copyKey(L.r[j+1],L.r[j]);
//记录后移
}
copyKey(L.r[j+1],L.r[0]);
//插入到正确的位置
}
}//InsertSort
//*************************希尔排序*************************\
voidshellInsert(SqList&
L,intdk)
{//对顺序表L做一希尔插入排序。
//1.前后记录位置的增量式是dk,而不是1;
//2.r[0]只是暂存单元,不是哨兵。
当j<
=0时,插入位置已找到
for(inti=dk+1;
i<
if(LT(L.r[i].key,L.r[i-dk].key))
{//需将L.r[i]插入到有序增量子表
copyKey(L.r[0],L.r[i]);
//暂存在L.r[0]中
for(intj=i-dk;
j>
0&
&
LT(L.r[0].key,L.r[j].key);
j-=dk)
copyKey(L.r[j+dk],L.r[j]);
copyKey(L.r[j+dk],L.r[0]);
//插入
}//ShellInsert
voidShellSort(SqList&
L,intdlta[],intt)
{//按增量序列dlta[0……t-1]对顺序表L作希尔排序
for(intk=0;
k<
t;
++k)
shellInsert(L,dlta[k]);
//一趟增量为dlta[k]的插入排序
}//ShellSort
//**************起泡排序****************************\
voidBublleSort(SqList&
inti=L.length;
while(i>
1)
intlastExchangeIndex=1;
for(intj=1;
j<
i;
j++)
{
if(LT(L.r[j+1].key,L.r[j].key))//小于成立进行交换
swap(L.r[j+1],L.r[j]);
lastExchangeIndex=j;
i=lastExchangeIndex;
}//BubbleSort
/***************************简单选择排序********************/
intSelectMinKey(SqListL,inti)
{//在L.r[i..L.length]中选择key最小的记录
for(intj=i;
++j)
if(LT(L.r[j].key,L.r[i].key))
i=j;
returni;
//返回最小记录下标
}
voidSelectSort(SqList&
{//对顺序表做简单选择排序for(inti=1;
L.length;
{//选择第i小的记录,并交换到位
intj=SelectMinKey(L,i);
//令j为L.r[i..L.length]中选择key最小的记录
if(i!
=j)
swap(L.r[j],L.r[i]);
//与第i记录进行交换
}//SelecteSort
/*********************快速排序*************/
intPartition(SqList&
L,intlow,inthigh)
{//交换顺序表L中字表r[low……high]的记录,枢轴记录到位,并
//返回其所在位置,此时在他之前(后)的记录均不大(小)与它。
copyKey(L.r[0],L.r[low]);
//用字表的第一个纪录作枢轴记录
KeyTypepivotkey=L.r[low].key;
//枢轴记录关键字
while(low<
high)
{//从表的两端交替向中间扫描
while(low<
high&
!
LT(L.r[high].key,pivotkey))--high;
copyKey(L.r[low],L.r[high]);
//将比枢轴记录小的记录移到低端
high&
LT(pivotkey,L.r[low].key))++low;
copyKey(L.r[high],L.r[low]);
//将比枢轴记录大的记录移到高端
copyKey(L.r[low],L.r[0]);
//枢轴记录到位
returnlow;
//返回枢轴位置
}//Partition
voidQSort(SqList&
{//对顺序表L中的子序列L.r[low……high]做快速排序
if(low<
{//长度>
1
intpivotloc=Partition(L,low,high);
//将L.r[low……high]一分为二
QSort(L,low,pivotloc-1);
//对低子表递归排序,pivotloc是枢轴位置
QSort(L,pivotloc+1,high);
//对高子表递归排序
}//QSort
voidQuickSort(SqList&
{//对顺序表L做快速排序
QSort(L,1,L.length);
}//QuickSort
/*************************堆排序*********************/
voidHeapAdjust(SqList&
L,ints,intm)
{//已知L.r[s...m]中记录的关键字除L.r[s].key之外均满足定义,
//本函数调整H.r[s]的关键字,使H.r[s...m]成为一个大顶对
RedTyperc=L.r[s];
for(intj=2*s;
=m;
j*=2)
{//沿key较大的孩子结点向下帅选
if(j<
m&
LT(L.r[j].key,L.r[j+1].key))++j;
//j为key较大的记录的下标
if(!
LT(rc.key,L.r[j].key))break;
//rc应插入在位置s上
copyKey(L.r[s],L.r[j]);
s=j;
L.r[s]=rc;
}//HeapAdjust
voidHeapSort(SqList&
{//对顺序表L进行堆排序
for(inti=L.length/2;
i>
0;
--i)
//把L.r[1....H.length]建成大顶堆
HeapAdjust(L,i,L.length);
for(i=L.length;
i>
1;
--i)
swap(L.r[1],L.r[i]);
//将堆顶记录和当前未经排序的子序列
//L.r[1……i]中最后一个记录进行交换
HeapAdjust(L,1,i-1);
//将L.r[1....i-1]重新调整为大顶堆
}//HeapSort
2.主函数和其他辅助函数的伪码算法
#include<
stdlib.h>
//产生随机数所需的库函数
/*****************************主函数************************/
intmain()
intarry[MAXSIZE+1];
//存放排序前数组
inttypeChoice;
//根据提示键入的类型选择序号
intmethodChoice;
//根据提示键入的方法选择序号
intseed;
//用于产生随机数的种子
PrintArrayMenu();
//打印选择待排序表的类型菜单
switch(typeChoice)
case1:
选择的是顺序表,初始化链表并打印
break;
case2:
选择的是逆序表,初始化链表并打印
case3:
选择的是随机数表
srand(seed);
//初始化随机数,并利用rand()产生随机数并打印
default:
cout<
<
L.length;
//打印待排序数组的长度
PrintMenu();
//打印排序方法选择菜单
while(methodChoice!
=7)
getChoice(L,choice);
//根据选择的方法堆表进行排序操作并打印相关信息
for(j=1;
=MAXSIZE;
j++)
{//将链表恢复至未排序时状态
L.r[j].key=arry[j];
return0;
/****************根据选择排序********************/
voidgetChoice(SqList&
L,intc)
{//根据选择进行排序并输出相关信息
intArray[3]={5,3,1};
//希尔排序所需增量数组
switch(c)
InsertSort(L);
//直接插入排序
outPut(L);
//输出关键字比较次数和移动次数
ShellSort(L,Array,3);
//希尔排序
//输出关键字比较次数和移动次数
BublleSort(L);
//起泡排序
case4:
SelectSort(L);
//简单选择排序
case5:
QuickSort(L);
//快速排序
case6:
HeapSort(L);
//堆排序
case7:
排序结束
3.函数的调用关系图反映了程序的层次结构
InsertSort
顺序表ShellSort
BublleSort
逆序表getTypeChoicegetMethodChoice
SelectSort
随机数表QuickSort
HeapSort
srandrand
4、排序算法结果比较
测试
直接插入排序
希尔排序
起泡排序
简单选择排序
快速排序
堆排序
表长
顺序表
19/0
51/0
209/0
190/76
121/118
20
逆序表
209/228
110/108
190/570
209/30
200/76
105/100
随即表1
134/147
105/85
184/345
209/51
105/76
115/109
随即表2
106/119
119/101
174/261
209/45
114/72
118/109
随即表3
99/108
107/84
165/240
209/42
107/74
119/118
随即表4
123/134
117/98
176/312
209/48
104/82
109/106
随即表5
140/153
189/363
119/72
107/101
随即表6
24962887/24972872
5153988/5146226
49981281/74858664
50004999/29976
226064/75760
235476/144261
10000
随即表7
25067619/25077602
5161759/5153799
49952164/75172860
50004999/29964
225821/76130
235408/144248
随即表8
24951520/24961493
5183866/5176131
49904576/74824563
50004999/29970
223755/75818
235241/144179
随即表9
25231354/25241327
5240599/5232732
49959846/75664065
50004999/29982
216797/75786
235488/144253
随即表10
24940230/24950219
5166043/5158198
49952854/74790693
50004999/29967
210437/76844
235432/144304
对各种表长和测试组数进行了测试,程序运行正常。
分析实测得到的数值,六种排序算法的特点小结如下:
比较次数
第三多
越乱越多
第三少乱否差异小
第二多越乱越多
最多与乱否无关
最少乱否差异小
第二少乱否差异小
移动次数
第二多
最多
越乱越多
五、附录
源程序文件名清单:
SqList.H//可排序表的实现
main.C//主程序
6、实验中遇到的问题及解决办法
1.程序采取循序渐进的策略。
首先设计和实现可排序表的建立操作,根据要求因包括随机数序列、正序和逆序三种情况,为避免不必要的错误,程序采用了先定义了两个数组,分别为正序和逆序,程序运行时分别将数组的值赋给链表的方式进行顺序表的建立,另外,起初对于随机数的产生产生了疑惑,但随后通过搜集资料成功的使用srand(seed)和rand()函数得到解决。
然后用插入排序验证了各种内部辅助操作的正确性,进而逐个加入其他排序算法,最后完成对测试结果的显示。
2.程序旨在进行六种排序方法优劣性的比较,在进行对六种排序依次排序时,出现了进行过依次排序后,排序表变为正序表而之后的集中排序方法都是在进行正序表的排序,而没有达到想要的效果,最后在主函数中添加了一个数组,用于记录原排序表的顺序,并在每次排序之后利用该数组对排序表进行再次建立,使得问题成功解决。
3.开始编程之初,总会出现关键字比较和移动次数的计算错误,在程序中进行逐步记录既繁琐又易出错,之后经过思考,建立了copyKey()和swap()函数,成功提高了程序效率并降低了计算错误率。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程设计 内部 排序 算法 比较