课程:《Java软件结构与数据结构》

班级: 1723

姓名: 侯泽洋

学号:20172302

实验教师:王志强老师

实验日期:2018年11月19日

必修/选修: 必修

实验内容

  • (1)定义一个Searching和Sorting类,并在类中实现linearSearch(教材P162 ),SelectionSort方法(P169),最后完成测试。要求不少于10个测试用例,提交测试用例设计情况(正常,异常,边界,正序,逆序),用例数据中要包含自己学号的后四位提交运行结果图。

  • (2)重构你的代码,把Sorting.java Searching.java放入 cn.edu.besti.cs1723.(姓名首字母+四位学号) 包中(例如:cn.edu.besti.cs1723.G2301),把测试代码放test包中,重新编译,运行代码,提交编译,运行的截图(IDEA,命令行两种)

  • (3)参考http://www.cnblogs.com/maybe2030/p/4715035.html 在Searching中补充查找算法并测试,提交运行结果截图

  • (4)补充实现课上讲过的排序方法:希尔排序,堆排序,二叉树排序等(至少3个)测试实现的算法(正常,异常,边界)提交运行结果截图

  • (5)编写Android程序对各种查找与排序算法进行测试,提交运行结果截图,推送代码到码云

实验过程及结果

(1)实验一

定义一个Searching和Sorting类,并在类中实现linearSearch(教材P162 ),SelectionSort方法(P169)

SelectionSort方法测试:

测试正常情况:

@Test
public void testNormal() throws Exception
{
Integer[] integers1 = {2,7,12,13,14,23,29,32,46,56};
Integer[] integers2 = {7,32,12,46,14,56,29,13,23,2};
Sorting.selectionSort(integers2);
for (int i=0;i<integers2.length;i++)
assertEquals(integers1[i],integers2[i]);
}

测试异常情况:

    @Test
public void testAbnormal() throws Exception
{
Integer[] integers1 = {2,7,12,13,14,23,29,32,46,56};
Integer[] integers2 = {7,32,12,46,14,56,29,14,23,2};
Sorting.selectionSort(integers2);
boolean result1 = true;
for (int i =0 ;i<integers2.length;i++)
{
if (integers1[i]!=integers2[i])
{
result1 = false;
break;
}
}
assertEquals(false,result1);
}

测试边界情况:

    @Test
public void testBoundary () throws Exception{
Integer[] integers1 = {2,7,12,13,14,23,29,32,46,8961};
Integer[] integers2 = {7,32,12,46,14,8961,29,14,23,2};
Sorting.selectionSort(integers2);
boolean result1 = true;
for (int i =0 ;i<integers2.length;i++)
{
if (integers1[i]!=integers2[i])
{
result1 = false;
break;
}
}
assertEquals(false,result1);
}

测试逆序:

    @Test
public void testReversed() throws Exception
{
Integer[] integers1 = {56,46,32,29,23,14,13,12,7,2};
Integer[] integers2 = {7,32,12,46,14,56,29,13,23,2};
Sorting.selectionSort(integers2);
for (int i=0;i<integers2.length;i++)
assertEquals(integers1[integers1.length-1-i],integers2[i]);
}

测试结果:



[测试用例代码]https://gitee.com/CS-IMIS-23/Java-pro/commit/6fff44510202eac172b3cbd26756c6554797802d

(2)实验二

  • 重构代码,把Sorting.java Searching.java放入 cn.edu.besti.cs1723.(姓名首字母+四位学号) 包中(例如:cn.edu.besti.cs1723.G2301),把测试代码放test包中,重新编译,运行代码,提交编译,运行的截图(IDEA,命令行两种)

    时间不够没有完成命令行,虚拟机也卸载掉了,只完成了第一种IDEA,对代码重构,放入指定包中。



(3)实验三

参考http://www.cnblogs.com/maybe2030/p/4715035.html 在Searching中补充查找算法并测试,提交运行结果截图

七种查找算法:线性查找、二分查找、插值查找、斐波那契查找、树表查找、分块查找、哈希查找

七种里面,斐波那契查找分块查找是两个新学的,也比较有意思

斐波那契查找的原理是利用斐波那契数列的特性来进行查找的,不是以二分的比列来查找,而是按照黄金比列0.618来进行分割查找,这样做的好处是:

关于斐波那契查找, 如果要查找的记录在右侧,则左侧的数据都不用再判断了,不断反复进行下去,对处于当众的大部分数据,其工作效率要高一些。所以尽管斐波那契查找的时间复杂度也为O(logn),但就平均性能来说,斐波那契查找要优于折半查找。可惜如果是最坏的情况,比如这里key=1,那么始终都处于左侧在查找,则查找效率低于折半查找。

还有关键一点,折半查找是进行加法与除法运算的(mid=(low+high)/2),插值查找则进行更复杂的四则运算(mid = low + (high - low) * ((key - a[low]) / (a[high] - a[low]))),而斐波那契查找只进行最简单的加减法运算(mid = low + F[k-1] - 1),在海量数据的查找过程中,这种细微的差别可能会影响最终的效率。

代码实现:

/*构造一个斐波那契数组*/
public static void Fibonacci(int[] F)
{
F[0]=0;
F[1]=1;
for(int i=2;i<max_size;++i)
F[i]=F[i-1]+F[i-2];
} //斐波那契查找
public static <T extends Comparable<? super T>>
boolean FibonacciSearch(T[] data, int min, int max, T target)
{
int length = max - min +1; int[] F = new int[max_size];
Fibonacci(F); int k=0;
while (length>(F[k]-1))
{
k++;
}
Object[] temp = new Object[max_size];
System.arraycopy(data,0,temp,0,data.length-1);
for (int i=length;i<F[k]-1;i++)
{
temp[i] = data[length-1];
}
while(min<=max)
{
int mid=min+F[k-1]-1;
if(target.compareTo((T) temp[mid])<0)
{
max=mid-1;
k-=1;
}
else if(target.compareTo((T)temp[mid])>0)
{
min=mid+1;
k-=2;
}
else
{
return true;
}
}
return false;
}

分块查找给我的第一感觉是快速排序算法,这进行划分,就用了原快速排序算法中的partition方法,我将整个数组分成了四块,进行了三次划分,然后根据比较结果确定元素所在区域,然后进行线性查找。

public static <T extends Comparable<? super T>>
boolean partitionSearch(T[] data, int min, int max, T target)
{
boolean result = false;
int partition1 = partition(data,min,max); int partition2 = partition(data,min,partition1-1);
int partition3 = partition(data,partition1+1,max); if (target.compareTo(data[partition1])==0)
return true;
else
{
if (target.compareTo(data[partition1])<0)
{
if (target.compareTo(data[partition2])==0)
return true;
else
{
if (target.compareTo(data[partition2])<0)
result = linearSearch(data,min,partition2-1,target);
else
result = linearSearch(data,partition2+1,partition1-1,target);
}
}
else
{
if (target.compareTo(data[partition3])==0)
return true;
else
{
if (target.compareTo(data[partition3])<0)
result = linearSearch(data,partition1+1,partition3-1,target);
else
result = linearSearch(data,partition3+1,max,target);
}
}
}
return result;
}

(4)实验四

补充实现课上讲过的排序方法:希尔排序,堆排序,二叉树排序等

希尔排序是新学的部分,一开始我对这里的希尔排序和之前做过的一个冒泡排序的升级的间隔排序法分辨不清,怎么也弄不明白这两个有什么区别,问题会记录这里。

将无序数组分割为若干个子序列,子序列不是逐段分割的,而是相隔特定的增量的子序列,对各个子序列进行插入排序;然后再选择一个更小的增量,再将数组分割为多个子序列进行排序......最后选择增量为1,即使用直接插入排序,使最终数组成为有序。

增量的选择:在每趟的排序过程都有一个增量,至少满足一个规则 增量关系 d[1] > d[2] > d[3] >..> d[t] = 1 (t趟排序);根据增量序列的选取其时间复杂度也会有变化,这个不少论文进行了研究,在此处就不再深究;本文采用首选增量为n/2,以此递推,每次增量为原先的1/2,直到增量为1;





实现代码:

public static <T extends Comparable<T>>void heapSort(T[] data)
{
LinkedHeap<T> linkedHeap = new LinkedHeap<>();
for (int i=0;i<data.length;i++)
linkedHeap.addElement(data[i]);
for (int i=0;i<data.length;i++)
data[i] = linkedHeap.removeMin();
}

实验代码非常简单。

(5)实验五

编写Android程序对各种查找与排序算法进行测试,提交运行结果截图,推送代码到码云

在Android上把这些算法都进行了测试,录了一个短的视频。

[链接]:https://www.mosoteach.cn/web/index.php?c=interaction_homework&m=homework_result_list&clazz_course_id=8CE1B708-B1CE-11E8-AA22-7CD30AD36C02&id=45E962C9-D25E-E6A1-697E-5820A8FAC84E

[代码链接]:https://gitee.com/CS-IMIS-23/Java-pro/commit/5b4d837f976592fbed90a14a3e7e194bc63997fd

实验过程中遇到的问题和解决过程

  • 问题1:关于泛型数组如何实例化?直接这样T[] temp = new T[];出现错误。

  • 问题1解决方案:参照书上之前的代码进行实例化

T[] array;
array = (T[]) new Object[10];

还找到一种方法是数组就是Object类型,使用再将Object类型强制转化为T类型也是可以。

  • 问题2:希尔排序和间隔排序法的一个区别?

  • 问题2解决方案:

    希尔排序是对间隔为一定距离的这些元素,全部进行排序,也就是说,经过这么一次排序之后,那么间隔为该距离的元素构成的一个集合一定是已排序好的。

    而间隔排序做的是从最开始元素开始,对这些元素,把大的放在后面,一次排序后,间隔为该距离的元素构成的集合不一定有序。但最后面的那个一定是最大的。

    举个简单的例子:

    对 {9 7 6 4 3}进行排序

    希尔排序第一轮

    间隔为2进行,得到 3 4 6 7 9 即 3、6、9是有序的,4、7是有序的。

    间隔排序第一轮

    得到 6 4 3 7 9,即9放到了后面,7也被放到了后面。

    这就产生了差别,两者在实现的代码上也有较大区别。

其他(感悟、思考等)

  • 本次实验主要的是排序和查找的算法的一些设计,帮助我们复习了之前的内容,同时也为接下来的Android开发提供了一个方向。

参考资料

20172302 《Java软件结构与数据结构》实验三:查找与排序实验报告的更多相关文章

  1. 20172302 《Java软件结构与数据结构》实验二:树实验报告

    课程:<Java软件结构与数据结构> 班级: 1723 姓名: 侯泽洋 学号:20172302 实验教师:王志强老师 实验日期:2018年11月5日 必修/选修: 必修 实验内容 (1)参 ...

  2. 20172302 《Java软件结构与数据结构》实验一:线性结构实验报告

    课程:<Java软件结构与数据结构> 班级: 1723 姓名: 侯泽洋 学号:20172302 实验教师:王志强老师 实验日期:2018年9月26日 必修/选修: 必修 实验内容 (1)链 ...

  3. 20172301 《Java软件结构与数据结构》实验三报告

    20172301 <Java软件结构与数据结构>实验三报告 课程:<Java软件结构与数据结构> 班级: 1723 姓名: 郭恺 学号:20172301 实验教师:王志强老师 ...

  4. 20172329 2018-2019 《Java软件结构与数据结构》实验三报告

    20172329 2018-2019-2 <Java软件结构与数据结构>实验三报告 课程:<Java软件结构与数据结构> 班级: 1723 姓名: 王文彬 学号:2017232 ...

  5. 20172309 《Java软件结构与数据结构》实验三报告

    课程:<程序设计与数据结构(下)> 班级:1723 姓名: 王志伟 学号:20172309 实验教师:王志强老师 实验日期:2018年11月2日 必修/选修: 必修 实验内容: 实验一: ...

  6. 20172301 《Java软件结构与数据结构》实验二报告

    20172301 <Java软件结构与数据结构>实验二报告 课程:<Java软件结构与数据结构> 班级: 1723 姓名: 郭恺 学号:20172301 实验教师:王志强老师 ...

  7. 20172329 2018-2019-2 《Java软件结构与数据结构》实验二报告

    20172329 2018-2019-2 <Java软件结构与数据结构>实验二报告 课程:<Java软件结构与数据结构> 班级: 1723 姓名: 王文彬 学号:2017232 ...

  8. 20172301 《Java软件结构与数据结构》实验一报告

    20172301 <Java软件结构与数据结构>实验一报告 课程:<Java软件结构与数据结构> 班级: 1723 姓名: 郭恺 学号:20172301 实验教师:王志强老师 ...

  9. 172322 2018-2019-1 《Java软件结构与数据结构》实验一报告

    172322 2018-2019-1 <Java软件结构与数据结构>实验一报告 课程:<程序设计与数据结构> 班级: 1723 姓名: 张昊然 学号:20172322 实验教师 ...

随机推荐

  1. flask_restplus(1)- 未完成

    快速开始 本指南假设您对Flask有一定的了解,并且您已经安装了Flask和Flask- restplus.如果没有,则按照安装部分中的步骤操作. 初始化 与其他所有扩展一样,您可以使用应用程序对象初 ...

  2. HTML学习笔记04-样式

    HTML<style>属性 style属性的作用: 提供了一种改变所有HTML元素样式的通用方法 background-colco属性为元素定义了背景颜色: <!DOCTYPE HT ...

  3. python实现监控windows服务控制开关服务

    转载自 :http://www.jb51.net/article/49106.htm #!/usr/bin/env python #-*- encoding:utf-8 -*- "" ...

  4. 调试Windows Service

    调试Windows Service 使用一般的调试方法调试不了Windows Servers,所以参考了一些调试方法 我服务源码中使用了Timer,注意不能使用工具箱内的Timer,用System.T ...

  5. 基于MFC的ActiveX控件开发教程------------浏览器插件之ActiveX开发

    浏览器插件之ActiveX开发(一) 一般的Web应用对于浏览器插件能不使用的建议尽量不使用,因为其涉及到安全问题以及影响用户安装(或自动下载注册安装)体验问题.在有特殊需求(如涉及数据安全的金融业务 ...

  6. linux压缩与解压

    1.tar -zcvf /home/aaa.tar.gz /xahot tar -zcvf 打包后生成的文件名全路径 要打包的目录 解压 #tar -zxvf /usr/local/test.tar. ...

  7. bzoj2152 树分治

    还是太菜了,自己写的wa,但是找不到哪里错了,, 感觉现在学树分治早了点..以后回来再看吧 /* 多少点对之间的路径是3的倍数 */ #include<iostream> #include ...

  8. cf 1041C双指针

    比赛的时候想着用单调队列做... 打完发现其实就是个双指针 /* 构造双指针解决即可 */ #include<iostream> #include<cstring> #incl ...

  9. 性能测试二十八:环境部署之Dubbo部署

    Zookeeper部署 ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件.它是一个为分布式应用提供一 ...

  10. 性能测试十三:linux常用命令

    常用的linux命令: 目录类/ 根目录. 当前目录.. 上级目录cd / 进入根目录cd .. 进入上级目录ls 查看当前目录下的所有文件ll 查看当前目录下所有文件的详细信息pwd 显示当前目录的 ...