课程:《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. redhat换用centos源

    解除原有源rpm -aq|grep yum|xargs rpm -e --nodepsrpm -aq|grep python-iniparse|xargs rpm -e --nodeps rpm -q ...

  2. eclipse指定项目编译级别

    指定项目编译级别Eclipse→Preferences→Java→Compiler→Compiler compliance level:1.6或其他 或者,

  3. centos6.5环境基于conga的web图形化界面方式配置rhcs集群

    一.简介 RHCS 即 RedHat Cluster Suite ,中文意思即红帽集群套件.红帽集群套件(RedHat Cluter Suite, RHCS)是一套综合的软件组件,可以通过在部署时采用 ...

  4. Ex 6_5棋子放置问题_第八次作业

    题目貌似有问题 (b) 子问题定义: 设maxValue[i][j]为棋盘的前i行中最后一行为i时第i行按照第j种放置方式放置时得到的最大覆盖值,comp[i][j]为第i种放置方式与第j种放置方式是 ...

  5. citySelect省市区jQuery联动插件

    参考地址:http://blog.csdn.net/qq_33556185/article/details/50704446 参考地址:http://www.lanrenzhijia.com/jque ...

  6. ES6的相关信息

    ECMAScript 是什么? ECMAScript 是 Javascript 语言的标准.ECMA European Computer Manufactures Association(欧洲计算机制 ...

  7. node版本控制之nvm

    windows下安装nvm 用nvm-noinstall.zip安装 1.nvm是个啥?nvm是一个可以让你在同一台机器上安装和切换不同版本node的工具linux系统的github地址:点我如果你是 ...

  8. cf276E 两棵线段树分别维护dfs序和bfs序,好题回头再做

    搞了一晚上,错了,以后回头再来看 /* 对于每次更新,先处理其儿子方向,再处理其父亲方向 处理父亲方向时无法达到根,那么直接更新 如果能达到根,那么到兄弟链中去更新,使用bfs序 最后,查询结点v的结 ...

  9. python 全栈开发,Day121(DButils,websocket)

    昨日内容回顾 1.Flask路由 1.endpoint="user" # 反向url地址 2.url_address = url_for("user") 3.m ...

  10. python 全栈开发,Day83(博客系统子评论,后台管理,富文本编辑器kindeditor,bs4模块)

    一.子评论 必须点击回复,才是子评论!否则是根评论点击回复之后,定位到输入框,同时加入@评论者的用户名 定位输入框 focus focus:获取对象焦点触发事件 先做样式.点击回复之后,定位到输入框, ...