北邮数据结构实验报告实验四排序含源码Word文件下载.docx
《北邮数据结构实验报告实验四排序含源码Word文件下载.docx》由会员分享,可在线阅读,更多相关《北邮数据结构实验报告实验四排序含源码Word文件下载.docx(18页珍藏版)》请在冰豆网上搜索。
inti,j;
for(i=2;
i<
=L.length;
i++)
if(L.r[i].key<
L.r[i-1].key)
L.r[0]=L.r[i];
L.r[i]=L.r[i-1];
for(j=i-2;
(L.r[0].key<
L.r[j].key);
j--)L.r[j+1]=L.r[j];
L.r[j+1]=L.r[0];
}
(2)、希尔排序的算法函数ShellSort()。
voidShellSort(SqList&
inti,j;
intdk=1;
//增量
while(dk<
=L.length/3)
dk=3*dk+1;
//增大增量
while(dk>
0)
dk/=3;
//减小增量
for(i=dk;
i<
i++){
L.r[0].key=L.r[i].key;
j=i;
while((j>
=dk)&
&
(L.r[j-dk].key>
L.r[0].key)){
L.r[j].key=L.r[j-dk].key;
j-=dk;
L.r[j].key=L.r[0].key;
(3)、冒泡排序算法函数BubbleSort()。
voidBubbleSort(SqList&
for(i=0;
i<
L.length-2;
intflag=1;
for(j=0;
j<
L.length-i-2;
j++)
if(L.r[j].key>
L.r[j+1].key)
flag=0;
inttemp;
temp=L.r[j].key;
L.r[j].key=L.r[j+1].key;
L.r[j+1].key=temp;
//若无交换说明已经有序
if(flag==1)
break;
}}
(4)、快速排序的算法函数Partition()。
(5)、选择排序算法函数SelectSort()。
voidSelectSort(SqList&
intmin;
intj;
for(inti=0;
L.length;
i++)
{//选择第i小的记录,并交换
min=L.r[i].key;
for(intk=i;
k<
L.length;
k++)
{//在R[i..n-1]中选择最小的记录
if(L.r[k].key<
min)
min=L.r[k].key;
j=k;
if(i!
=j)
{//与第i个记录交换
inttemp=L.r[i].key;
L.r[i].key=L.r[j].key;
L.r[j].key=temp;
(6)、堆排序算法函数HeapAdjust()。
voidHeapAdjust(HeapType&
H,ints,intm)
第6/10页
//堆调整,将记录调整为小顶堆intj;
RedTyperc=H.r[s];
//暂时存储根结点
for(j=2*s;
j<
=m;
j*=2)
//沿着结点记录较小的向下筛选
if(j<
m&
H.r[j].key<
H.r[j+1].key)
++j;
if(rc.key>
=H.r[j].key)
H.r[s]=H.r[j];
s=j;
H.r[s]=rc;
voidHeapSort(HeapType&
H)
inti;
RedTypetemp;
for(i=H.length;
i>
0;
--i)
HeapAdjust(H,i,H.length);
for(i=H.length;
1;
temp=H.r[1];
H.r[1]=H.r[i];
H.r[i]=temp;
HeapAdjust(H,1,i-1);
(7)、对存储数字的遍历函数Visit()、初始化函数InitSqList()。
voidVisit(SqListL)
for(inti=1;
cout<
<
L.r[i].key<
"
"
;
endl;
voidInitSqList(SqList&
L,inta[])
L.r[i].key=a[i];
(8)、主函数main()。
关键算法的时间、空间复杂度:
排序法
平均时间
最差情形
稳定度
额外空间
备注
冒泡
O(n2)
稳定
O
(1)
n小时较好
交换
不稳定
选择
插入
大部分已排序时较好
Shell
O(nlogn)
O(ns)1<
s<
2
s是所选分组
快速
n大时较好
归并
堆
2.3其他
3.程序运行结果
主函数流程:
4.总结
首先,对程序的设计缺少优化,本次程序需要运行之后手动进行输入数据,以后可以尝试把数据改为在源代码中输入,这样就可以运行之后马上显示数据,这样就避免了相同数据的重复输入。
此外,生成数组函数及本程序中的代码有的采用了递归形式,如果考虑用栈来模拟的话,效率会有提升,所以运行时间还和代码的实现有关。
本程序出现过的问题是主函数对个函数的调用以及对存储数组的调用上出现了问题,导致排序的结果以及排序的界面出现了问题,得不到实现。
后来对算法进行改进,最终把问题得以解决。
而且以后可以试着去写一段可以计算出时间的函数。
代码
#include<
iostream>
#include<
time.h>
windows.h>
usingnamespacestd;
inti,j,temp,k;
//设置全局变量
longdoubleGetNowTime()//取系统时间
LARGE_INTEGERlitmp;
LONG64QPart;
QueryPerformanceCounter(&
litmp);
QPart=litmp.QuadPart;
return(longdouble)QPart;
//插入排序
voidInsertSort(intr[],intn)
{intmove=0,compare=0;
longdoublestart=0,end=0,time=0;
start=GetNowTime();
for(i=2;
n;
{
if(r[i]<
r[i-1])//记录后项小于记录前项时进行排序
{compare++;
r[0]=r[i];
//设置哨兵,存放待排序记录值
for(j=i-1;
r[0]<
r[j];
j--,compare++)//寻找插入位置
r[j+1]=r[j];
//比r[0]大的往后移
r[j+1]=r[0];
//插入指定记录值
move=move+3;
//关键码的交换按3次记
compare++;
}
}
end=GetNowTime();
time=end-start;
for(k=1;
k<
k++)
cout<
r[k]<
//输出排序后记录
cout<
排序所需时间:
time<
us移动次数:
move<
比较次数:
compare;
endl<
//希尔排序
voidShellSort(intr[],intn)
intmove=0,compare=0;
start=start=GetNowTime();
intd;
//定义增量
for(d=n/2;
d>
=1;
d=d/2)//以增量为d进行直接插入排序
for(i=d+1;
{
//设置哨兵,暂存被插入记录
for(j=i-d;
j>
0&
j=j-d,compare++)
r[j+d]=r[j];
//记录后移d个位置
r[j+d]=r[0];
move=move+3;
compare++;
for(i=1;
r[i]<
//改进型起泡排序
voidBubbleSort(intr[],intn)
intexchange;
intbound;
exchange=n-1;
//第一趟起泡排序的范围是r[0]到r[n-1]
while(exchange)//仅当上一趟排序有记录交换才进行本趟排序
bound=exchange;
//表示无序的范围
exchange=0;
for(intj=0;
bound;
j++,compare++)//一趟起泡排序
if(r[j]>
r[j+1])
temp=r[j];
//交换r[i]和r[i+1]
r[j]=r[j+1];
r[j+1]=temp;
move=move+3;
exchange=j;
//记录每一次发生记录交换的位置,即记录无序区的位置
compare++;
for(inti=0;
us移动次数:
//快速排序一次划分
intEmove=0,Ecompare=0;
longdoubleEtime;
intPartition(intr[],intfirst,intend)
i=first;
//初始化
j=end;
while(i<
j)//循环的停止条件是i=j
while(i<
j&
=r[j])
{Ecompare++;
j--;
}//右侧扫描
Ecompare++;
if(i<
j)
temp=r[i];
//将较小记录交换到前面
r[i]=r[j];
r[j]=temp;
Emove=Emove+3;
/*i++;
*/
i++;
}//左侧扫描,小于轴值的不移动,找到大于轴值的
r[j]=r[i];
r[i]=temp;
//将较大记录交换到后面
/*j--;
*/
returni;
//i为轴值记录的最终位置
//快速排序,在一次排序结束后,左边区的元素都比右边区的小,只要分开再排序即可
voidQuickSort(intr[],intfirst,intend2)
longdoublestart=0,end=0;
if(first<
end2)
{//递归结束
intpivot=Partition(r,first,end2);
//一次划分
QuickSort(r,first,pivot-1);
//递归地对左侧子序列进行快速排序
QuickSort(r,pivot+1,end2);
//递归地对右侧子序列进行快速排序
Etime=end-start;
voidPrint()
Etime<
us;
移动的次数:
Emove<
比较的次数:
Ecompare<
//简单选择排序,每一趟都找到最小值与比较域内第一个值交换
voidSelectSort(intr[],intn)
intcompare=0,move=0;
intindex;
//设置关键值下标
for(i=0;
n-1;
i++)//对n个记录进行n-1趟简单选择排序
index=i;
for(j=i+1;
j++,compare++)//在无序区中选取最小记录
if(r[j]<
r[index])//有记录小于关键值记录
index=j;
//更新关键值记录
if(index!
=i)//若第一个是最小值就不用交换
{
temp=r[i];
r[i]=r[index];
r[index]=temp;
//交换r[i]和关键值记录
move=move+3;
}
//对数列进行排序
voidpx(intr[],intnumv)
\n直接顺序排序结果为:
InsertSort(r,numv);
希尔排序结果为:
ShellSort(r,numv);
起泡排序结果为:
BubbleSort(r,numv-1);
快速排序结果为:
QuickSort(r,0,numv-1);
numv-1;
Print();
Emove=0;
Ecompare=0;
\n"
简单选择排序结果为:
SelectSort(r,numv-1);
//主函数
intmain()
constintnumv=11;
inta[numv]={0};
intb[numv]={0};
intc[numv]={0};
请输入10位正整数."
第一组,正序输入a[]="
try
for(i=1;
numv;
cin>
>
a[i];
//从键盘输入待排序记录值
catch(char*wrong)
wrong;
px(a,numv);
//调用排序函数
\n第二组,反序输入b[]="
cin>
b[i];
px(b,numv);
\n第三组,随机输入c[]="
c[i];
px(c,numv);
return0;