101几种基本排序算法的实现.docx
《101几种基本排序算法的实现.docx》由会员分享,可在线阅读,更多相关《101几种基本排序算法的实现.docx(14页珍藏版)》请在冰豆网上搜索。
101几种基本排序算法的实现
数据结构实验报告
实验题目:
几种基本排序算法的实现
姓名:
张耀
班级:
计嵌151
学号:
1513052017
一、实验目的
实现直接插入排序,冒泡排序,简单选择排序,快速排序,希尔排序,堆排序等6种常用内部排序算法,比较各算法的比较次数和移动次数。
二、数据结构设计
(1)设计待排序记录的存储结构。
(2)设计待排序数据的存储结构。
(3)输入:
待排序数据的数据个数和数据可由键盘输入,也可由程序生成伪随机数,以菜单方式选择上述排序方法中的一个,并指明输出第几趟排序的结果。
(4)输出:
各趟排序结果或指定趟的排序结果,以及对应的关键字比较次数和移动次数。
三、算法设计与N-S图
算法设计:
编写一个主函数main(),在主函数中设计一个简单的菜单,分别调用6种内部排序算法。
为了对各种排序算法的性能进行比较,算法中的主要工作是在已知算法的适当位置插入对关键字的比较次数和移动次数的计数操作。
为此,可设立一个实现排序算法中的关键字比较的函数;设立一个实现排序算法中的关键字移动的函数;设立一个实现排序算法中的关键字交换的函数,从而解决比较次数和移动次数的统计问题。
数据的输入也可以通过菜单选择输入方式:
键盘输入或由伪随机数程序生成数据,以便随时更换排序数据,并按照不同要求对排序数据进行排序,输出排序的结果以及对应的关键字比较次数和移动次数。
对于测试数据,算法中可以考虑几组数据的典型性,如正序,逆序和不同程度等,以取得直观的感受,从而对不同算法进行比较。
四、程序清单
#include
usingnamespacestd;
voidshowMenu()
{
cout<<"*菜单*"<cout<<"1.直接插入排序"<cout<<"2.冒泡排序"<cout<<"3.简单选择排序"<cout<<"4.快速排序"<cout<<"5.希尔排序"<cout<<"6.堆排序"<cout<<"7.退出程序"<}
structSqList{
int*key;
intlength;
};
voidCreateSqList(SqList&sl)//type为int
{
intn;
cout<<"建立顺序表"<cin>>n;
sl.length=n;
sl.key=newint[sl.length+1];
cout<<"请输入数据:
"<for(inti=1;i<=sl.length;i++)
{
cin>>sl.key[i];
}
}
voidCopy(SqList&L1,SqList&L2)
{
L2.length=L1.length;
L2.key=newint[L1.length+1];
for(inti=1;i<=L1.length;i++)
{
L2.key[i]=L1.key[i];
}
}
voidOutPut(SqList&L)
{
for(intj=1;j<=L.length;++j)
cout<cout<}
voidInsertSort(SqList&L)
{//对顺序表L作直接插入排序
intk=0;
intcompare_Time,move_Time;
compare_Time=move_Time=0;
for(inti=2;i<=L.length;i++)
{
if(L.key[i]<=L.key[i-1])//"<"需将L.key[i]插入有序子表
{
L.key[0]=L.key[i];//复制为哨兵
L.key[i]=L.key[i-1];
intj;
for(j=i-2;L.key[0]<=L.key[j];--j)
{
compare_Time++;
L.key[j+1]=L.key[j];//记录后移
move_Time++;
}
L.key[j+1]=L.key[0];//插入到正确位置
k++;
cout<<"第"<";OutPut(L);
}
compare_Time++;
}
cout<<"比较次数为:
"<cout<<"移动次数为:
"<}
voidBubbleSort(SqList&L)
{
intk=0;
intcompare_Time,move_Time;
compare_Time=move_Time=0;
for(inti=1;i{
intt;
for(intj=1;j<=L.length-i;j++)
{
compare_Time++;
if(L.key[j]>L.key[j+1])
{
t=L.key[j];
L.key[j]=L.key[j+1];
L.key[j+1]=t;
move_Time++;
}
}
k++;
cout<<"第"<";OutPut(L);
}
cout<<"比较次数为:
"<cout<<"移动次数为:
"<}
intSelectMinKey(SqList&L,intn,int&compare_Time)
{
intmin=n;
intminkey;//最小值
minkey=L.key[n];
for(inti=n+1;i<=L.length;i++)
{
if(L.key[i]{
minkey=L.key[i];
min=i;
}
compare_Time++;
}
returnmin;
}
voidSelectSort(SqList&L)
{
//对顺序表L作简单选择排序
intj;
intt;
intk=0;
intmove_Time=0,compare_Time=0;
for(inti=1;i<=L.length;i++)
{
j=SelectMinKey(L,i,compare_Time);//在L.key[i]--L.key[L.length]中选择最小的记录并将其地址赋给j
if(i!
=j)//交换记录
{
t=L.key[i];
L.key[i]=L.key[j];
L.key[j]=t;
move_Time++;
}
compare_Time++;
k++;
cout<<"第"<";OutPut(L);
}
cout<<"比较次数为:
"<cout<<"移动次数为:
"<}
intPartition(SqList&L,intlow,inthigh,int&compare_Time,int&move_Time)
{//交换顺序表L中子表key[low]--key[high]中的记录,枢轴记录到位,并返回其所在位置,
//此时在它之前(后)的记录均不大(小)于它
intpivotkey;
L.key[0]=L.key[low];//用子表的第一个记录作枢轴记录
pivotkey=L.key[low];//关键字
while(low{
compare_Time++;
while(low=pivotkey)--high;
L.key[low]=L.key[high];
move_Time++;//将比枢轴小的记录移至低端
while(lowL.key[high]=L.key[low];//将比枢轴大的记录移至高端
move_Time++;
}
L.key[low]=L.key[0];//枢轴记录到位
returnlow;//返回枢轴位置
}
voidQSort(SqList&L,intlow,inthigh,int&k,int&compare_Time,int&move_Time)
{
intmid;//接收枢轴位置
if(low{
mid=Partition(L,low,high,compare_Time,move_Time);
k++;
cout<<"第"<";OutPut(L);
QSort(L,low,mid-1,k,compare_Time,move_Time);//对低子表进行排序
QSort(L,mid+1,high,k,compare_Time,move_Time);//对高子表进行排序
}
}
voidQuitSort(SqList&L)//对顺序表进行快速排序
{
intk=0;
intcompare_Time=0,move_Time=0;
QSort(L,1,L.length,k,compare_Time,move_Time);
cout<<"比较次数为:
"<cout<<"移动次数为:
"<}
voidShellInsert(SqList&L,intdk,int&compare_Time,int&move_Time)
{//对顺序表进行一趟希尔插入排序
for(inti=dk+1;i<=L.length;i++)
if(L.key[i]<=L.key[i-dk])
{
compare_Time++;
L.key[0]=L.key[i];
intj;
for(j=i-dk;j>0&&L.key[0]<=L.key[j];j-=dk)
{
compare_Time++;
L.key[j+dk]=L.key[j];
move_Time++;
}
L.key[j+dk]=L.key[0];
}
}
voidShellSort(SqList&L,intdlta[],intt)
{
intcompare_Time=0,move_Time=0;
//按增量序列dl[0]--dl[t-1]对顺序表L作哈希排序
for(intk=0;k{
ShellInsert(L,dlta[k],compare_Time,move_Time);
cout<<"第"<";OutPut(L);
}
cout<<"比较次数为:
"<cout<<"移动次数为:
"<}
voidHeapAdjust(SqList&L,ints,intm,int&compare_Time,int&move_Time)
{//对顺序表做查找,从值最大的孩子结点向下筛选,找到最大值
intrc=L.key[s];
for(intj=2*s;j<=m;j*=2)
{
if(j{
j++;
}
compare_Time++;
if(rc>L.key[j])break;//如果rc最大则推出while循环
L.key[s]=L.key[j];//最大值赋值
s=j;//交换位置
move_Time++;
}
L.key[s]=rc;
}
voidHeapSort(SqList&L)
{//对顺序表L进行堆排序
intvalue,i;
intk=0;
intcompare_Time=0,move_Time=0;
for(i=L.length/2;i>0;i--)//把L.key[1...L.length]调整为大顶堆
HeapAdjust(L,i,L.length,compare_Time,move_Time);
for(i=L.length;i>1;--i)
{
value=L.key[1];
L.key[1]=L.key[i];
L.key[i]=value;
HeapAdjust(L,1,i-1,compare_Time,move_Time);//将L.key[1...i-1]重新调整为大顶堆
k++;
cout<<"第"<";OutPut(L);
}
cout<<"比较次数为:
"<cout<<"移动次数为:
"<}
intmain()
{
intchoice;
SqListsq,sp;
CreateSqList(sq);
Copy(sq,sp);
showMenu();
cout<<"Pleaseenteryourchoice:
";
cin>>choice;
while(choice!
=0)
{
switch(choice)
{
case1:
InsertSort(sq);cout<<"最终结果:
";
OutPut(sq);break;
case2:
BubbleSort(sq);cout<<"最终结果:
";
OutPut(sq);break;
case3:
SelectSort(sq);cout<<"最终结果:
";
OutPut(sq);break;
case4:
QuitSort(sq);cout<<"最终结果:
";
OutPut(sq);break;
case5:
int*p,n;
cout<<"请输入增量个数:
"<cin>>n;
p=newint[n];
cout<<"请输入各个增量的值:
"<for(inti=0;i{
cin>>p[i];
}
ShellSort(sq,p,n);cout<<"最终结果:
";
OutPut(sq);break;
case6:
HeapSort(sq);cout<<"最终结果:
";
OutPut(sq);break;
case7:
cout<<"程序运行结束,退出程序。
"<return0;break;
}
Copy(sp,sq);
showMenu();
cout<<"Pleaseenteryourchoice:
";
cin>>choice;
}
return0;
}
五、运行与测试
六、实验分析及体会
通过这次试验主要让我们深入了解了各种排序的不同特点和排序原理,各种排序在时间复杂度和空间复杂度上均各有差异,对于不同的排序案例,我们可以根据他们各自的特点挑选最佳的排序方案。
今后在实际操作中会注意各个排序的特点正确的运用。
2017,加油!