查找是在某个项目组中寻找到某一指定目标元素,或者肯定该指定目标并不存在。html
高效的查找会使该过程所作的比较操做次数最小化。java
静态方法(类方法)能够经过类名调用,不能引用实例变量,能够引用静态变量。Java程序的main方法必须用static修饰符(声明为静态)来修饰,解释器不用实例化含有main的类的对象,就能够调用main方法。git
泛型方法建立一个引用泛型的方法,只需在方法头的返回类型前插入一个泛型声明便可。含有返回类型和参数类型的方法,就可使用泛型参数。泛型声明必须位于返回类型以前,这样泛型才能够做为返回类型的一部分。算法
线性查找时间复杂度O(n)从列表头开始依次比较每个值,直至找到该目标,结果是要么找到目标,要么到达列表尾并得出该组中不存在该目标的结论。编程
二分查找时间复杂度O(logn)从排序列表的中间开始查找,若是中间元素不是目标元素,则继续取半搜索。在每一次比较操做后,将排除剩余待搜索的一半数据。数组
选择排序算法经过反复的将某一特定值放到它在列表中的最终已排序位置,从而完成对某一列值的排序。安全
插入排序算法经过反复地将某一特定值插入到该列表某个已排序的字集中来完成对列表值的排序。数据结构
冒泡排序算法经过重复地比较相邻元素且在必要时(彼此不符顺序)将它们互换,从而完成対值的排序。
性能
快速排序经过使用任意选定的分区元素将该列表分区,而后对分区元素的任一边的子列表进行递归排序。
学习
归并排序算法是经过将列表递归式分红两半直至每一子列表都只含有一个元素,而后将这些子列表归并到一个排序顺序中,从而完成对列表的排序。
基数排序是基于队列处理的,经过排序关键字的部份,将要排序的元素分配至某些队列中,经过出队入队以达到排序的做用。
追问(2.) 泛型的上下限有什么做用?
- 和泛型的下限表示方法相似,<? extends T>表示的是泛型的上限。super表示包括T在内的任何T的父类,extends表示包括T在内的任何T的子类。 “有界类型”的泛型避免了强制类型转换的同时保留了安全性能,使得转换有了必定的限制。在必定程度上提升了代码的灵活性,随便用相关的类。
追问(3.)<T extends Comparable<T>>
和 <T extends Comparable<? super T>>或<T extends Comparable<? extends T>>
有什么不一样?
- 少了?和super,二者的意义会有很大的变化,前者表示的是类型T必须实现Comparable接口,而且这个接口的类型是T。只有实现接口的T的实例才会相互比较,然后者是表示类型T必须实现Comparable接口,而且接口的类型是T或者是T的任一父类或子类。
建立具备继承关系的类,一个是Anima类,另外一个是Cat类。可是在Animal中实现了Comparable
sort1(Animal)
结果是正常按照年龄进行排序,sort1(cat)
结果会报错。仅由于Animal实现了接口Comparable
sort2(Animal)
和sort2(Cat)
的结果均按照年龄进行排序。(比较的参数类型不一样在后者的状况下也能够进行比较,大大的提升了代码的灵活性与自由度。)追问(4.)若是在子类中实现Comparable接口的话是否能够改善sort1比较的差别?
- 若是父类实现了接口,那么子类就继承了相关的接口不能从新实现接口;相反只能重写父类CompareTo的方法来达到进行子类的比较。
问题2解决方案:泛型方法的定义和普通方法定义不一样的地方在于须要在修饰符和返回类型之间加一个泛型类型参数的声明,代表在这个方法做用域中谁才是泛型类型参数,规定了泛型的范围,从这一点能够看出罚你性能高的优点就是提升了代码的灵活性。
- 泛型类,是在实例化类的时候指明泛型的具体类型;泛型方法,是在调用方法的时候指明泛型的具体类型。
问题3解决方案:
public static <T> boolean linearSearch(T[] data, int min, int max, T target) { int index = min; boolean found = false; while (!found && index <= max) { found = data[index].equals(target); index++; } return found; }
针对这串代码个人第一想法就是用二分查找替代这种线性查找,可是不符合老师的要求。整串代码可以优化的部分就是while循环里面的!found
、index <= max
、found = data[index].equals(target)
、index++
四部分,我以为能够把!found
和found = data[index].equals(target)
进行合并,这样能够i吉安少一条语句的运行,但实质上并无进行变化一样的判断与测试看似两条语句变一条语句,其程度遍复杂了,要执行一次比较,在进行一次布尔型的判断。而老师给出的答案是设立一个哨兵,也就是数组索引值为0的位置加入目标元素,若是在未遍历到头就结束的话就能判断数组内含有该元素,并且找到该元素;若是到哨兵的位置找到的话,那就说明没有该元素,也就是不用判断index <= max
示例答案中并无判断是否到了尾部的相关代码。(示例代码并没与在复杂度上解决该问题,可是在性能上有所提升。针对这一结果也是醉了)
data[0] = target; for (index = data.length-1; !data[indax].equals(target);--index){ } return index == 0? false:true;
在第一次改写的时候没有动内外循环,只是把数组交换的索引值改了,结果就报数组越界异常(ArrayIndexOutOfBoundsException)。实际上是由于在增长间隔的时候外循环仍是在一个个的遍历,致使数组的越界。
第二次稀里糊涂的改了个内层循环的条件结果是能够进行排序,可是末尾的两个元素或是三个元素(间隔次数不一样)始终不排序,考虑到多是间隔不为1的时候尾部两个元素或是三个元素没有排序,在达到间隔为1的时候有直接跳出没排致使的(感受本身第二次修改的时候好迷)。
第三次进行了大修改,由于考虑到间隔次数是在递减正好替换以数组长度为外层循环条件,再在内外层循环之间进行一个遍历的循环使交换的时候能多进行几回,而内层循环在经历过第二次排序后发如今间隔次数未达到1的状况下数组元素始终有小于间隔次数的元素没有进行排列,而此刻的索引值最大就是数组长度减去间隔次数。
我的以为在进行间隔数减少的过程当中包含了冒泡排序的过程,而仅使用冒泡排序就能够达到排序的目的,间隔排序效率并不高,实现的过程还特别麻烦,一堆循环的叠加,以为这种排序方法除非是进行间隔几个元素的状况下进行排列的类型,其他状况下好像用处并不大。
问题2解决方案:时间代码在放假的时候就看了一部分,接触的相关类都是像Calendar计算多少天、多少年的类以及SimpleDateFormat进行格式化输出时间的类和LocalDate记录日期的类。而System.nanoTime()在上网查找以后发现是以long形式输出系统计时器的当前值,而后两个值进行相减就能够表示出运行时间。在类的开头可结尾各方一个进行记录在相减就能够了。
time++
如何在递归方法中实现?问题3解决方案:对于含有递归方法的相关代码,若是把记录次数的代码放的位置稍有不对就会形成不断的输出或是一直归零,针对选择排序、插入排序和冒泡排序彻底在方法题中添加些代码,在循环体中进行那个自增计数就能够了。而快速排序和归并排序就不行,一直在不断输出,经过借鉴侯泽洋同窗的博客,发现能够建立全局变量来实现就输出一次,在递归方法中进行自增,在调用递归的方法中进行输出;或是从新设定一个方法,使以前的递归方法被调用,这样再进行以前的实现步骤就行。
本周结对学习状况
20172314方艺雯
20172323王禹涵
结对学习内容:查找和排序
第六章的内容是用数组和链表表示列表的,在必定还曾独上列表和队列、栈都有必定程度上的类似,部分代码彻底能够以前编写的,惟一以为比较恶心的就是在添加的过程当中就直接被排序。经过这几章学的内容,对链表和数组有了更多的认识,应用起来也比较顺手。勤能补拙,多练习多尝试总没有错的。
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 0/0 | 1/1 | 15/15 | |
第二周 | 703/703 | 1/2 | 20/35 | |
第三周 | 762/1465 | 1/3 | 20/55 | |
第四周 | 2073/3538 | 1/4 | 40/95 | |
第五周 | 981/4519 | 2/6 | 40/135 |