课程:《程序设计与数据结构》
班级: 1723
姓名: 王禹涵
学号:20172323
实验教师:王志强
实验日期:2018年11月20日
必修/选修: 必修html
查找与排序-1
定义一个Searching和Sorting类,并在类中实现linearSearch(教材P162 ),SelectionSort方法(P169),最后完成测试。
要求很多于10个测试用例,提交测试用例设计状况(正常,异常,边界,正序,逆序),用例数据中要包含本身学号的后四位
提交运行结果图。java
查找与排序-2
重构你的代码
把Sorting.java Searching.java放入 cn.edu.besti.cs1723.(姓名首字母+四位学号) 包中(例如:cn.edu.besti.cs1723.G2301)
把测试代码放test包中
从新编译,运行代码,提交编译,运行的截图(IDEA,命令行两种)git
查找与排序-3
参考http://www.cnblogs.com/maybe2030/p/4715035.html 在Searching中补充查找算法并测试
提交运行结果截图算法
查找与排序-4
补充实现课上讲过的排序方法:希尔排序,堆排序,二叉树排序等(至少3个)
测试实现的算法(正常,异常,边界)
提交运行结果截图数组
查找与排序-5
编写Android程序对各类查找与排序算法进行测试
提交运行结果截图
推送代码到码云数据结构
测试的代码(参照上学期的资源)性能
public void testSearch1() { assertEquals(true, SearchingSorting.linearSearch(search1, 0, 6, 2323)); }
左下角反映了测试经过与否单元测试
第二部分看似简单,其实花费了我很多时间。
首先把代码类放在一个新的包内,另外一个测试类其实应该放在专门的test包内,而不该该随便就在src下建一个test包,这点在单元测试的讲解中有提到过,即学习
test目录中放的也是Java代码,但IDEA不知道test中放的是源代码。在命令行中咱们知道要设置
SOURCEPATH
环境变量,在IDEA中咱们右键单击test目录,在弹出的菜单中选择Mark Directory as->Test Sources Root
就能够了测试
另外一个在命令行上测试,我重写了测试方法,没有再用JUnit测试,由于屡次使用cmd运行都提示找不到或没法加载主类,重写以后,找到编译文件所在的位置java SSTest1
。特别奇怪的一个地方是,我只能在编译文件所在的包外运行该代码,若是是在包内又会报错。
须要理解几种查找算法,这部分比较困难,可是须要本身作的地方不难,由于代码基本都给了出来。重点须要新学的是斐波拉契查找和插值查找
int InsertionSearch(int a[], int value, int low, int high) { int mid = low+(value-a[low])/(a[high]-a[low])*(high-low); if(a[mid]==value) return mid; if(a[mid]>value) return InsertionSearch(a, value, low, mid-1); if(a[mid]<value) return InsertionSearch(a, value, mid+1, high); }
其余地方都和折半查找相似,主要是定位查找点的方法int mid = low+(value-a[low])/(a[high]-a[low])*(high-low);
很差理解
value = 2; low = 0; high = 19; mid = 1;
此时a[mid] = a[1] = 2,就查找到了须要的元素。
我想这个算法的核心在于(high - low)
反映了要查找的数组的长度,(value-a[low])/(a[high]-a[low])
定位了查找点大体在数组几分之几的位置上(由于数组内的元素分布是比较均匀的)。
代码分析
写出这代码的核心思想是什么我还没法理解,只能跟着代码走一遍。首先他须要将数组内的元素复制到一个斐波那契数长度的数组中,多出来的位置所有填充原数组的最后一位。而后经过变换mid的值不断缩小查找的范围,若是查找值小于temp[mid]的值,说明待查找的元素在[low,mid-1]范围内,反之说明待查找的元素在[mid+1,high]范围内。这里恰好前面一部分与后面一部分的比值约为0.618,将数组扩展到F[k]-1长度也是出于此考虑,以后相似于二分查找不断缩小范围逼近查找值。但最后的值有可能在扩展的数组中,须要返回n-1(为何最多只会找到扩展数组的第一个位置尚未弄明白)
题目给出的三种排序算法,堆排序在以前的项目中已经有了实现的方法,二叉树排序也不困难,只须要将数组内的元素依次序添加进二叉树中,而后按照中序输出的方法也能达到排序的效果。主要是希尔排序没有遇到过
代码实现
public static void sort(Integer[] data){ if(data == null || data.length <= 1){ return; } //增量 int incrementNum = data.length/2; while(incrementNum >=1){ for(int i=0;i<data.length;i++){ //进行插入排序 for(int j=i;j<data.length-incrementNum;j=j+incrementNum){ if(data[j]>data[j+incrementNum]){ int temple = data[j]; data[j] = data[j+incrementNum]; data[j+incrementNum] = temple; } } } //设置新的增量 incrementNum = incrementNum / 2; } String str = ""; for (int n = 0; n < data.length; n++){ str += data[n] + " "; } System.out.println(str); }
从算法的实现能够看出,希尔排序是有些相似与间隔排序的,它经过设置增量,将相同间隔的元素放在一堆而后排好序,再将增量扩大,直至全部元素都在一个数组中且进行排序,这时即排序完成
这部分还算比较简单,就把以前的代码移动到AS里,不过同时还须要移动一大堆的相关文件过去。我比较省事地只添加了两个按钮,一键就调用全部的排序或者查找方法。而后textview.setView()中输出一大堆返回信息,如图
问题1:进行插值查找时,查找一个数组中不存在的数,出现以下的错误
问题1解决方案:debug以后发如今进行分区域的时候,会出现low>high的状况,而程序没有能处理这种状况的能力。参照斐波那契查找代码中对于出现low>high状况的处理,在外部加上一个while循环,当出现low>high时,直接return -1
这样一来错误状况就处理掉了。
问题2:int型与Interger型的区别
问题2解决方案:之前历来没有考虑到过这个问题(多是没有认真学习的缘由),总之到此次实验时才发觉他俩好像是有点小小的区别,由于第一部分的实验新创的数组都是Comparable型的,但后来由于实验须要有一些方法有须要转换成int型,因此数值的比较方法也须要大改。按理说data[min].compareTo(data[j]) > 0
就须要改为data[min] > data[j]
可是改为Interger型这些都不须要改变。因此查了一下他俩的一些区别
Integer 类和 int 的区别
①、Integer 是 int 包装类,int 是八大基本数据类型之一(byte,char,short,int,long,float,double,boolean)
②、Integer 是类,默认值为null,int是基本数据类型,默认值为0;
③、Integer 表示的是对象,用一个引用指向这个对象,而int是基本数据类型,直接存储数值。
Interger型至关因而一个包装盒,里面包含的是int型的对象,因此可使用CompareTo的方法。
此次实验相对来讲理论的学习很重要,要优于本身动手写代码。经过此次实验,我对几种查找和排序算法都有了更深入的了解,同时还了解了一些没有接触过的查找算法。比较意外的一个收获是,我对一些数据类型的了解也更加深入了
《Java程序设计与数据结构教程(第二版)》