数据结构实验报告实验4
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构实验报告
实验名称:实验四排序(题目1)
学生姓名:
班级:
班内序号:
学号:
日期:2013年12月19日
1.实验要求
实验目的:学习、实现、对比各种排序算法,掌握各种排序算法的优劣,以及各种算法使用的情况。
实验内容:
使用简单数组实现下面各种排序算法,并进行比较。
排序算法:
1、插入排序
2、希尔排序
3、冒泡排序
4、快速排序
5、简单选择排序
6、堆排序
7、其他
要求:
1、测试数据分成三类:正序、逆序、随机数据
2、对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字
交换计为3次移动)。
3、对2的结果进行分析,验证上述各种算法的时间复杂度。
编写测试main()函数测试线性表的正确性。
2. 程序分析
2.1 存储结构
程序采用的存储机构是顺序存储,如下图所示:
2.2 关键算法分析
2.2.1 插入排序
插入排序的基本方法是寻找一个指定元素在待排序元素中的位置,然后插入。一趟直接插入排序的C++描述过程如下:
①将待插入纪录赋值给哨兵r[0]:r [0]=r [i];
②从后向前进行顺序查找:for (j=i-1;r [0]<r [j];j--); ③元素后插:r [j+1]=r [j]; ④插入记录:r [j+1]=r [j]; 性能分析:
原序列正序时直接插入排序达到最好的时间性能,比较次数为n -1,移动次数为0。原序
列逆序时直接插入排序达到最差时间性能,比较次数为
∑=n i i 2
,移动次数为∑=+n
i i 2
)1(。
直接插入排序的平均时间复杂度为)(2
n O ,空间复杂度为)1(O 。
直接插入排序是一种稳定的排序算法,特别适合于待排序集合基本有序的情况。 2.2.2 希尔排序 希尔排序的基本方法是将待排序的元素集分成多个子集,分别对这些子集进行直接插入
排序,待整个序列基本有序时,再对元素进行一次直接插入排序。
希尔排序的整个过程如下:
for (int d=n /2;d>=1;d=d/2) //以d 为增量 //在子序列中进行插入排序
{ for (int i=d+1;i<=n ;i++) //一趟希尔排序 { if (r [i]<r [i-d]) { r [0]=r [i];
for (int j=i-d;j>0&&r [0]<r [j];j=j-d)
//每隔d 个记录,进行一次比较和移动,d=1时即是最后一趟直接插入排序
r [j+d]=r [j]; r [j+d]=r [0];
}
}
}
性能分析:
希尔排序的时间复杂度在)(2
n O 和)log (2n n O 之间,空间复杂度为)1(O ,是一种
不稳定的排序算法。
2.2.3 冒泡排序
冒泡排序的基本思想是,两两比较相邻的元素,如果反序,则交换位置,知道没有反序
的元素为止。
具体描述如下:
//外循环:总共需要遍历的趟数
for (int i=1;i<n;i++)
{
//内循环:每一趟需要比较的次数
for (int j=1;j<=n-i;j++)
{
if (r[j]>r[j+1]) //相邻元素比较
{
r[0]=r[j];r[j]=r[j+1];r[j+1]=r[0];
//若逆序,则交换
}
}
}
性能分析:
原序列正序时冒泡排序达到最好的时间性能,比较次数为n-1,移动次数为0。原序列逆
序时达到最差时间性能,比较次数为∑-
=-
1
1
) (
n
i
i
n,移动次数为∑-
=
-
1
1
)
(
n
i
i
n。平均时间复杂度为
)
(2n
O,空间复杂度为)1(
O。冒泡排序是一种稳定的排序算法。
2.2.4 快速排序
快速排序是冒泡排序的改进算法,快速排序元素的比较和移动是从两端向中间进行的,因而元素移动的距离较远。快速排序的基本思想是,在分区中选择一个元素作为轴值,将待排序元素划分成两个分区,使得左侧元素的关键码均小于或等于轴值,右侧元素的关键码均大于或等于轴值,然后分别对这两个分区重复上述过程直到整个序列有序。
经过优化改进的快速排序算法如下:
//一趟快速排序
int Partion(int r[],int first,int end)
{
int i=first;int j=end;
int pivot=r[i]; //选取基准元素
while(i<j)
{
while((i<j)&&(r[j]>=pivot)) //右侧扫描
{
j--;
}
r[i]=r[j];
while((i<j)&&(r[i]<=pivot)) //左侧扫描
{
i++;
}
r[j]=r[i];