数据结构实验 排序.docx
《数据结构实验 排序.docx》由会员分享,可在线阅读,更多相关《数据结构实验 排序.docx(11页珍藏版)》请在冰豆网上搜索。
![数据结构实验 排序.docx](https://file1.bdocx.com/fileroot1/2022-11/22/859ff71c-0698-488b-99fd-355d6d397a14/859ff71c-0698-488b-99fd-355d6d397a141.gif)
数据结构实验排序
实验报告
学生姓名:
黄家明学号:
6103115017专业班级:
计科151班
实验类型:
□验证□综合□设计□创新实验日期:
2017/5/24实验成绩:
一、实验目的
深入了解各种内部排序方法及效率分析。
二、问题描述
各种内部排序算法的时间复杂度分析,试通过随机数据比较算法的关键字比较次数和关键字移动次数。
三、实验要求
1、对起泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、堆排序这六种常用排序算法进行比较。
2、待排序表的表长不超过100;其中数据用伪随机数产生程序产生。
1、至少要用6组不同的输入数据做比较。
2、要对实验结果做简单分析。
四、实验环境
PC微机
DOS操作系统或Windows操作系统
TurboC程序集成环境或VisualC++程序集成环境
五、实验步骤
1、根据问题描述写出基本算法。
2、设计六种排序算法并用适当语言实现。
3、输入几组随机数据,并对其关键字比较次数和关键字移动次数的比较。
4、对结果进行分析。
5、进行总结。
六、测试数据
数据有随机数产生器产生。
七、实验结果
随机数产生器产生器代码,利用rand(),srand()产生随机数
#include
usingnamespacestd;
intmain()
{
//测试数据输出到data.in文件中
freopen("/Users/huangjiaming/Documents/Algorithm/src/data.in","w",stdout);
intn;
srand((unsigned)time(0));
while(~scanf("%d",&n))
{
printf("%d\n",n);
for(inti=0;iprintf("%d",rand()%10000);
printf("\n");
}
return0;
}
冒泡排序的实现代码:
voidBubbleSort(intarr[],intn)
{
doublestart=clock();
printf("排序数据大小:
%d,冒泡排序后:
\n",n);
for(inti=0;ifor(intj=i;jif(a[i]>a[j])
a[i]^=a[j]^=a[i]^=a[j];
doubleend=clock();
print(a,n);
printf("冒泡排序花费的时间=%.6lfs\n\n",(double)(end-start)/CLOCKS_PER_SEC);
}
直接插入排序的实现代码:
voidinsertsort(intarr[],intn)
{
doublestart=clock();
printf("排序数据大小:
%d,直接插入排序后:
\n",n);
for(inti=1;i{
//[0,i-1]都是有序的。
如果待插入元素比arr[i-1]还大则无需再与[i-1]前面的元素进行比较了,反之则进入if语句
if(arr[i]{
inttemp=arr[i];
intj;
for(j=i-1;j>=0&&arr[j]>temp;j--)
arr[j+1]=arr[j];//把比temp大或相等的元素全部往后移动一个位置
arr[j+1]=temp;//把待排序的元素temp插入腾出位置的(j+1)
}
}
doubleend=clock();
print(a,n);
printf("直接插入排序花费的时间=%.6lfs\n\n",(double)(end-start)/CLOCKS_PER_SEC);
}
简单选择排序的实现代码:
voidselectionSort(intarr[],intn)
{
doublestart=clock();
printf("排序数据大小:
%d,简单选择排序后:
\n",n);
for(inti=0;iintmin=i;
//找出本轮中最小的位置
for(intj=i+1;jif(arr[j]min=j;
}
}
//把第i小的和第i位置元素交换
inttemp=arr[i];
arr[i]=arr[min];
arr[min]=temp;
}
doubleend=clock();
print(a,n);
printf("简单选择排序花费的时间=%.6lfs\n\n",(double)(end-start)/CLOCKS_PER_SEC);
}
快速排序的实现代码:
voidquickSort(intarr[],intleft,intright)
{
if(left>right)
return;
inttemp=arr[left];//temp中为基准数
inti=left,j=right;
while(i!
=j)
{
//从右边开始找
while(arr[j]>=temp&&ij--;
//再从左边开始找
while(arr[i]<=temp&&ii++;
if(i{
intt=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
}
arr[left]=arr[i];
arr[i]=temp;
quickSort(arr,left,i-1);
quickSort(arr,i+1,right);
}
希尔排序的实现代码:
voidshellSort(intarr[],intn)
{
doublestart=clock();
printf("排序数据大小:
%d,简单选择排序后:
\n",n);
intstep=n/2;//初始增量
while(step>0)
{
//无序部分
for(inti=step;iinttemp=arr[i];
intj;
//子序列中的插入排序,这是有序部分
for(j=i-step;j>=0&&temp//在找到当前元素合适位置前,元素后移
arr[j+step]=arr[j];
arr[j+step]=temp;
}
step/=2;
}
doubleend=clock();
print(a,n);
printf("希尔选择排序花费的时间=%.6lfs\n\n",(double)(end-start)/CLOCKS_PER_SEC);
}
堆排序实现代码
voidadjustHeap(intarr[],intp,intlen)
{
intcurParent=arr[p];
intchild=2*p+1;//左孩子
while(childif(child+1child++;//较大孩子的下标
}
if(curParentarr[p]=arr[child];
//没有将curParent赋值给孩子是因为还要迭代子树,
//如果其孩子中有大的,会上移,curParent还要继续下移。
p=child;
child=2*p+1;
}
else
break;
}
arr[p]=curParent;
}
voidheapSort(intarr[],intlen)
{
//建立堆,从最底层的父节点开始
for(inti=len/2-1;i>=0;i--)
adjustHeap(arr,i,len);
for(inti=len-1;i>=0;i--)
{
intmaxEle=arr[0];
arr[0]=arr[i];
arr[i]=maxEle;
adjustHeap(arr,0,i);
}
}
实验过程如下,生成随机数,总共三组,数据大小分别为10、1000、10000
1、冒泡排序测试
排序消耗的时间分别为0.000025s、0.002381s、0.312073s,时间复杂度为O(n2)
2、直接插入排序测试
排序消耗的时间分别为0.000086s、0.001031s、0.082690s,时间复杂度为O(n2)
3、简单选择排序测试
排序消耗的时间分别为0.000025s、0.001450s、0.135557s,时间复杂度为O(n2)
4、快速排序测试
排序消耗的时间分别为0.000027s、0.00119s、0.001427s,时间复杂度为O(n*log2n)
5、希尔排序测试
排序消耗的时间分别为0.000067s、0.00167s、0.002567s,时间复杂度不确定
6、堆排序测试
排序消耗的时间分别为0.000024s、0.00118s、0.001859s,时间复杂度O(n*log2n)
八、问题以及思考
经过实验,可以得出
排序法
最差时间分析
平均时间复杂度
稳定度
空间复杂度
冒泡排序
O(n2)
O(n2)
稳定
O
(1)
快速排序
O(n2)
O(n*log2n)
不稳定
O(log2n)~O(n)
选择排序
O(n2)
O(n2)
稳定
O
(1)
插入排序
O(n2)
O(n2)
稳定
O
(1)
堆排序
O(n*log2n)
O(n*log2n)
不稳定
O
(1)
希尔排序
O
O
不稳定
O
(1)
而在实验结果中,对于数据比较大的测试,它们之间的排序效率差异较为明显。