2010级数据结构实验报告
实验名称:排序
姓名:袁彬
班级: 2009211120
班内序号: 09
学号: 09210552
日期: 2010 年12 月19 日
1.实验要求
试验目的:
通过选择试验内容中的两个题目之一,学习、实现、对比各种排序的算法,掌握各种排序算法的优缺点,以及各种算法使用的情况。
试验内容:
题目一:
使用简单数组实现下面各种排序算法,并进行比较。
排序算法如下:
①插入排序;
②希尔排序
③冒泡排序;
④快速排序;
⑤简单选择排序;
⑥堆排序
⑦归并排序
⑧基数排序
⑨其他。
具体要求如下:
①测试数据分为三类:正序,逆序,随机数据。
②对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换记为三次移动)。
③对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微妙。
④对②和③的结果进行分析,验证上述各种算法的时间复杂度。
⑤编写main()函数测试各种排序算法的正确性。
题目二:
使用链表实现下面各种排序算法,并进行比较。
排序算法如下:
①插入排序;
②冒泡排序;
③快速排序;
④简单选择排序;
⑤其他。
具体要求如下:
①测试数据分为三类:正序,逆序,随机数据。
②对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换记为三次移动)。
③对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微妙(选作)
④对②和③的结果进行分析,验证上述各种算法的时间复杂度。
⑤编写main()函数测试各种排序算法的正确性。
2. 程序分析
2.1 存储结构
程序中每一个算法均是用一个类来表示的,类中有自己的构造函数、排序函数。
程序的储存结构采用数组。数组的第一个位置不存储数据。数据从第二个位置开始。数组中的相对位置为数组的下标。
2.2 关键算法分析
㈠、关键算法:
1、插入排序函数:Insert s ort(int n)
①、从2开始做循环,依次和前面的数进行比较:for(int i=2;i<=n;i++)
②、如果后面的比前面的小,则进行前移:if(number[i] ③、设置哨兵:number[0]=number[i]; ④、如果后面的比前面的小,前面的进行后移:for(j=i-1;number[0] ⑤、前面的进行后移:number[j+1]=number[j]; ⑥、将比较的数据放置到正确位置:number[j+1]=number[0]; 2、希尔排序函数:Shell i nsert(int n) ①、以长度的一半为间隔进行循环:for(int d=n/2;d>=1;d=d/2) ②、在自己的间隔中进行简单插入排序,进行循环:for(int i=d+1;i<=n;i++) ③、如果后面的数据比前面的小,进行前移:if(number[i] ④、设置哨兵:number[0]=number[i]; ⑤、在自己的间隔中进行简单插入排序:for(j=i-d;number[0] ⑥、大的数据后移:number[j+d]=number[j]; ⑦、哨兵归位:number[j+d]=number[0]; 3、冒泡排序函数:Bubble s ort(int n) ①、设置有序无序的边界点:int pos=n; ②、当边界点不为空进行循环:while(pos!=0) ③、边界点传递给bound:int bound=pos; ④、从开始到边界点进行循环:for(int i=1;i ⑤、如果前面的数据比后面的大,进行交换:if(number[i]>number[i+1]) ⑥、交换:number[0]=number[i];number[i]=number[i+1];number[i+1]=number[0]; ⑦、从小设置边界点:pos=i; 4、一趟快速排序函数:partion(int first,int end) ①、传递设置整个数据的起点和终点:int i=first;int j=end; ②、设置中轴:number[0]=number[i]; ③、当end大于first进行循环:while(i ④、当后面的数据大于中轴,后面的游标前移:while((i ⑤、中轴和比它大的数据进行交换:number[i]=number[j]; ⑥、当前面的数据小于中轴,前面的游标后移:while((i i++; ⑦、中轴和比它小的数据进行交换:number[j]=number[i]; ⑧、将中轴进行归位:number[i]=number[0]; 5、递归快速排序函数:Qsort(int i,int j) ①、如果数组不为空,进行排序:if(i ②、一趟冒泡排序:int pivotloc=partion(i,j); ③、递归将左右半面进行排序:Qsort(i,pivotloc-1);Qsort(pivotloc+1,j); 6、简单选择排序函数:Select s ort(int n) ①、从数组开始到结尾进行遍历:for(int i=1;i ②、设置最小数据标记:int index=i; ③、在无序区进行循环:for(int j=i+1;j<=n;j++) ④、当出现比标记还小的数据,就进行交换:if(number[j] ⑤、如果最小的不是末尾的数,就进行交换:if(index!=i) ⑥、进行交换: number[0]=number[i];number[i]=number[index];number[index]=number[0]; 7、一趟堆排序函数:sift(int k,int m) ①、设置根节点和孩子的位置:int i=k,j=2*k; ②、从左右孩子中选择出最小的孩子:if(j ③、判断根节点是不是最小的,不是就进行交换:if(number[i] ④、进行交换:number[0]=number[i];number[i]=number[j];number[j]=number[0]; ⑤、将根节点和孩子位置后移,继续排序:i=j;j=2*i; 8、递归堆排序函数:Heap s ort(int n) ①、从最大非叶子节点,进行一趟堆排序:for(i=n/2;i>=1;i--) ②、进行数组长度值的循环:for(i=1;i ③、将根节点和尾节点进行交换: number[0]=number[1];number[1]=number[n-i+1];number[n-i+1]=number[0]; ④、在进行一趟堆排序:sift(1,n-i); 9、一趟归并排序函数:Merge(int *r, int *r1, int s, int m, int t) ①、传递设置两个数组的起点和终点:int i=s;int j=m+1;int k=s; ②、当任意一个数组没有达到终点时,进行循环:while(i<=m&&j<=t) ③、进行循环,将较小的值传给r1数组:if(r[i] ④、将较小的值传给r1数组:r1[k++]=r[i++];else r1[k++]=r[j++]; ⑤、当一个数字已经比较完,做循环将其续借到r1数组中:if(i<=m)while(i<=m) r1[k++]=r[i++]; ⑤、当另一个数字已经比较完,做循环将其续借到r1数组中:if(j<=t)while(j<=t) r1[k++]=r[j++]; 10、递归归并排序函数:MergeSort(int *r, int *r1, int s, int t) ①、创建新数字指针存储排序序列:int *r2=new int[t]; ②、当序列中只有一个数据时,令其相等:if(s==t)r1[s]=r[s]; ③、否则,进行递归:else ④、将原数组折半:int m=(s+t)/2; ⑤、将前半数组进行递归调用:MergeSort(r,r2,s,m); ⑥、将后半数组进行递归调用:MergeSort(r,r2,m+1,t); ⑦、将数组进行递归调用:Merge(r2,r1,s,m,t); ㈡、关键算法的时间、空间复杂度 ①、直接插入排序函数:时间复杂度O(n2) ②、希尔排序函数:时间复杂度O(n㏒2 n) ③、起泡排序:时间复杂度O(n2) ④、快速排序:时间复杂度O(n㏒2 n) ⑤、简单选择排序:时间复杂度O(n2) ⑥、堆排序:时间复杂度O(n㏒2 n) ⑦、归并排序:时间复杂度O(n㏒2 n) 3. 程序运行结果 测试主函数流程: 程序流程图如下: 4. 总结 (1)、出现的问题及调试的方法 这次试验总的来说是比较简单的,因为这七种排序算法的代码书上都有,在理解的基础上参考书上的代码输入基本上不会有太大的问题,但问题还是有的。例如:一组待排序的整数存在一个数组中,当采用一种排序算法对这个数组进行排序后,数组就被修改了,变为有序的序列,这是一个问题,于是我动态申请了七个数组,每次排序对不同的数组进行,这个问题就解决了 (2)、心得体会 这次试验是我对排序运算有了深刻的理解,对我们课堂上的知识进行回顾。 在程序编译和链接时还报了一些错,最后我对排序运算有了深刻的理解,对我们课堂上的知识进行回顾。 在程序编译和链接时还报了一些错,最后通过一步一步的测试,也很快解决了问题。 通过这次程序我感觉我对C++调试有个很深的理解,对程序的调试有了很多心得,也对我的程序调试和编写有了进一步的提高。同时对C++编程进一步熟悉,同时对数据结构有了一个整体的认识,对各种排序中函数成员实现的原理、代码进一步了解。同时对各种排序的优缺点有了进一步的认识和了解。 在这个程序中,我觉得下一步程序可以进一步对时间复杂度进行优化,通过将程序的冗长的代码删除,优化算法等,让程序得到结果所需要的时间更短、更快,删除一些代码,让程序的空间复杂度和时间复杂度都减小。 (3)、下一步的改进 程序中代码有一部分不是太简洁,例如七个数组、统计比较了移动次数这些代码显得比较乱。 算法设计与分析基础 实验报告 应用数学学院 二零一六年六月 实验一插入排序算法 一、实验性质设计 二、实验学时14学时 三、实验目的 1、掌握插入排序的方法和原理。 2、掌握java语言实现该算法的一般流程。 四、实验内容 1、数组的输入。 2、输入、输出的异常处理。 3、插入排序的算法流程。 4、运行结果的输出。 五、实验报告 Ⅰ、算法原理 从左到右扫描有序的子数组,直到遇到一个大于(或小于)等于A[n-1]的元素,然后就把A[n-1]插在该元素的前面(或后面)。 插入排序基于递归思想。 Ⅱ、书中源代码 算法InsertionSort(A[0..n-1]) //用插入排序对给定数组A[0..n-1]排序 //输入:n个可排序元素构成的一个数组A[0..n-1] //输出:非降序排列的数组A[0..n-1] for i ←1 to n-1 do v ← A[i] j ← i-1 while j ≥0and A[j] > v do A[j+1] ← A[j] j ← j-1 A[j+1] ← v Ⅲ、Java算法代码: import java.util.*; public class Charu { public static void main(String[] args) { int n = 5; int a[] = new int[n]; int s = a.length; int i = 0, j = 0, v = 0; System.out.println("请输入若干个数字:"); Scanner sc = new Scanner(System.in); try { while (i < s) { a[i] = sc.nextInt(); i++; } for (i = 1; i 《数据结构》实验报告排序实验题目: 输入十个数,从插入排序,快速排序,选择排序三类算法中各选一种编程实现。 实验所使用的数据结构内容及编程思路: 1. 插入排序:直接插入排序的基本操作是,将一个记录到已排好序的有序表中,从而得到一个新的,记录增一得有序表。 一般情况下,第i 趟直接插入排序的操作为:在含有i-1 个记录的有序子序列r[1..i-1 ]中插入一个记录r[i ]后,变成含有i 个记录的有序子序列r[1..i ];并且,和顺序查找类似,为了在查找插入位置的过程中避免数组下标出界,在r [0]处设置哨兵。在自i-1 起往前搜索的过程中,可以同时后移记录。整个排序过程为进行n-1 趟插入,即:先将序列中的第一个记录看成是一个有序的子序列,然后从第2 个记录起逐个进行插入,直至整个序列变成按关键字非递减有序序列为止。 2. 快速排序:基本思想是,通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。 假设待排序的序列为{L.r[s] ,L.r[s+1],…L.r[t]}, 首先任意选取一个记录 (通常可选第一个记录L.r[s])作为枢轴(或支点)(PiVOt ),然后按下述原则重新排列其余记录:将所有关键字较它小的记录都安置在它的位置之前,将所有关键字较大的记录都安置在它的位置之后。由此可以该“枢轴”记录最后所罗的位置i 作为界线,将序列{L.r[s] ,… ,L.r[t]} 分割成两个子序列{L.r[i+1],L.[i+2], …,L.r[t]}。这个过程称为一趟快速排序,或一次划分。 一趟快速排序的具体做法是:附设两个指针lOw 和high ,他们的初值分别为lOw 和high ,设枢轴记录的关键字为PiVOtkey ,则首先从high 所指位置起向前搜索找到第一个关键字小于PiVOtkey 的记录和枢轴记录互相交换,然后从lOw 所指位置起向后搜索,找到第一个关键字大于PiVOtkey 的记录和枢轴记录互相 交换,重复这两不直至low=high 为止。 具体实现上述算法是,每交换一对记录需进行3 次记录移动(赋值)的操作。而实际上, 实验七查找、排序的应用 一、实验目的 1、本实验可以使学生更进一步巩固各种查找和排序的基本知识。 2、学会比较各种排序与查找算法的优劣。 3、学会针对所给问题选用最适合的算法。 4、掌握利用常用的排序与选择算法的思想来解决一般问题的方法和技巧。 二、实验内容 [问题描述] 对学生的基本信息进行管理。 [基本要求] 设计一个学生信息管理系统,学生对象至少要包含:学号、姓名、性别、成绩1、成绩2、总成绩等信息。要求实现以下功能:1.总成绩要求自动计算; 2.查询:分别给定学生学号、姓名、性别,能够查找到学生的基本信息(要求至少用两种查找算法实现); 3.排序:分别按学生的学号、成绩1、成绩2、总成绩进行排序(要求至少用两种排序算法实现)。 [测试数据] 由学生依据软件工程的测试技术自己确定。 三、实验前的准备工作 1、掌握哈希表的定义,哈希函数的构造方法。 2、掌握一些常用的查找方法。 1、掌握几种常用的排序方法。 2、掌握直接排序方法。 四、实验报告要求 1、实验报告要按照实验报告格式规范书写。 2、实验上要写出多批测试数据的运行结果。 3、结合运行结果,对程序进行分析。 五、算法设计 a、折半查找 设表长为n,low、high和mid分别指向待查元素所在区间的下界、上界和中点,key为给定值。初始时,令low=1,high=n,mid=(low+high)/2,让key与mid指向的记录比较, 若key==r[mid].key,查找成功 若key 《排序问题求解》实验报告 一、算法的基本思想 1、直接插入排序算法思想 直接插入排序的基本思想是将一个记录插入到已排好序的序列中,从而得到一个新的, 记录数增1 的有序序列。 直接插入排序算法的伪代码称为InsertionSort,它的参数是一个数组A[1..n],包含了n 个待排序的数。用伪代码表示直接插入排序算法如下: InsertionSort (A) for i←2 to n do key←A[i] //key 表示待插入数 //Insert A[i] into the sorted sequence A[1..i-1] j←i-1 while j>0 and A[j]>key do A[j+1]←A[j] j←j-1 A[j+1]←key 2、快速排序算法思想 快速排序算法的基本思想是,通过一趟排序将待排序序列分割成独立的两部分,其中一 部分记录的关键字均比另一部分记录的关键字小,则可对这两部分记录继续进行排序,以达到整个序列有序。 假设待排序序列为数组A[1..n],首先选取第一个数A[0],作为枢轴(pivot),然后按照下述原则重新排列其余数:将所有比A[0]大的数都排在它的位置之前,将所有比A[0]小的数都排在它的位置之后,由此以A[0]最后所在的位置i 作为分界线,将数组A[1..n]分成两个子数组A[1..i-1]和A[i+1..n]。这个过程称作一趟快速排序。通过递归调用快速排序,对子数组A[1..i-1]和A[i+1..n]排序。 一趟快速排序算法的伪代码称为Partition,它的参数是一个数组A[1..n]和两个指针low、high,设枢轴为pivotkey,则首先从high 所指位置起向前搜索,找到第一个小于pivotkey 的数,并将其移到低端,然后从low 所指位置起向后搜索,找到第一个大于pivotkey 的数,并将其移到高端,重复这两步直至low=high。最后,将枢轴移到正确的位置上。用伪代码表示一趟快速排序算法如下: Partition ( A, low, high) A[0]←A[low] //用数组的第一个记录做枢轴记录 privotkey←A[low] //枢轴记录关键字 while low 电子科技大学实验报告 课程名称:数据结构与算法 学生姓名: 学号: 点名序号: 指导教师: 实验地点:基础实验大楼 实验时间: 5月20日 2014-2015-2学期 信息与软件工程学院插入排序算法实验报告
= 0 && a[j] > v) { a[j + 1] = a[j]; j--; } a[j + 1] = v; } System.out.println("插入排序结果显示:"); for (i = 0; i < s; i++) { System.out.println(a[i]); } } catch (Exception es) { System.out.println(es); } } } Ⅳ、运行结果显示:《数据结构》实验报告——排序.docx
(完整word版)查找、排序的应用 实验报告
算法排序问题实验报告
实验报告-排序与查找