20182310 2019-2020-1 《数据结构与面向对象程序设计》第八周学习总结
教材学习内容总结
1.泛型
之前涉及过通过继承实现多态,而Object则是所有类型的父类,因此只要将一个数组指向Object类型,那么该数组理论上就可以保存所有类型的数据了,这是一种极端情况
但是,当使用了Object后,容易出现兄弟类型之间转换的问题,编译不会报错,但是运行时会出错。
泛型:可以定义一个类,可以保存数据及操作,但只有当实例化时才确定类型(一般用T来表示泛型)
class Box
{
T类型对象的声明与操作代码
}
当要使用Box定义的数据时,通过实例化来实现它的具体类型,来替代T
Box
Box
...
2.线性查找法
线性查找法就是从头开始查找,与每一个列表中的元素进行比较,直到找到该目标元素或查找到末尾还没找到。
以下的方法实现了一个线性查找。该方法返回一个布尔值,若是true,便是找到该元素,否则为false,表示没找到。
public static
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; }
二分查找法
二分查找是从排序列表(查找池是已排序的)的中间开始查找,而不是从一端或者另一端的开始的。通过比较,确定可行候选项就又减少了一半的元素量,以相同的方式继续查找,直到最后找到目标元素或者不再存在可行候选项。
二分查找的关键在于每次比较都会删除一半的可行候选项。
以下的方法实现了一个二分查找,其中的最大索引和最小索引定义了用于查找(可行候选项)的数组部分。
public static <T extends Comparable
boolean binarySearch(T[] data, int min, int max, T target)
{
boolean found = false;
int midpoint = (min + max) / 2; // determine the midpoint
if (data[midpoint].compareTo(target) == 0) found = true; else if (data[midpoint].compareTo(target) > 0) { if (min <= midpoint - 1) found = binarySearch(data, min, midpoint - 1, target); } else if (midpoint + 1 <= max) found = binarySearch(data, midpoint + 1, max, target); return found; }
}
注意:在该算法中,midpoint = (min + max) / 2,当min+max所得数值是基数的时候,会自动转化成int类型,直接忽略小数部分,也就是确定中点索引时选择的是两个中间值的第一个(小一点的)。
查找算法的比较
对于线性查找和二分查找,最好的情形都是目标元素恰好是我们考察的第一个元素,最坏的情形也都是目标不在该组中。因此,线性查找的时间复杂度为O(n),二分查找的时间复杂度为O(log2(n))。
当n比较大时,即元素特别多的时候,二分查找就会大大提高效率。而当n比较小的时候,线性查找更简单好调试且不需要排序,因此也在小型问题上常用线性查找。
3.排序
排序:基于某一标准,将某一组项目按照某个规定顺序排列。
顺序排序:通常使用一对嵌套循环对n个元素进行排序,需要大约n^2次比较。
对数排序:对n个元素进行排序通常大约需要nlog2(n)次比较。
常见的三种顺序排序:
①选择排序、②插入排序、③冒泡排序;
常见的两种对数排序:
①快速排序、②归并排序
选择排序:通过反复地找到某个最小(或者最大)元素,并把它放置到最后的位置来给元素排序。
插入排序:通过反复地把某个元素插入到之前已经排序的子列表中,实现元素的排序。
冒泡排序:通过反复的比较相邻元素并交换他们,来给元素排序。
快速排序:通过把未排序元素分隔成两个分区,然后递归地给每个分区排序。
快速排序的平均时间复杂度为O(nlogn)。在所有平均时间复杂度为O(nlogn)的算法中,快速排序的平均性能是最好的。
4.在JavaAPI中的ArrayList类和LinkedList类是由不同的底层结构实现的列表。
ArrayList类和LinkedList类都实现了java.util.List接口。List接口中的一些方法如图所示:
教材学习中的问题和解决过程
- 问题1:Queue接口两种方法add和offer在异常类处理上有何不同。
问题1解决方案add操作可以确保队列中有给定的元素。如果给定元素没有添加到队列中,该操作将抛出一个异常。
offer操作把给定元素插入到队列中,如果插入成功,返回true,否则返回false。- 问题2:ASL的含义
问题2解决方案:平均查找长度(Average Search Length,ASL):需和指定key进行比较的关键字的个数的期望值,称为查找算法在查找成功时的平均查找长度。用于衡量算法的效率。
代码调试中的问题和解决过程
- 问题1:关于null
- 问题1解决方案:null值不是任何对象的实例, 所以下面这个例子返回了false,无论这个变量声明的是什么类型。
String s = null;
if ( s instanceof String ) 强制上传后,:wq保存,然后重新git push即可。 - 问题2:用链表实现有序列表添加操作时候的空指针异常。
- 问题2解决方案:
public void add(T element) {
if (!(element instanceof Comparable))
throw new NonComparableElementException("OrderedList");
Comparable<T> comparableElement = (Comparable<T>)element; LinearNode<T> current = head; LinearNode<T> previous = null; LinearNode<T> node = new LinearNode<>(element); while (( current != null) && (comparableElement.compareTo(current.getElement()) > 0)) { previous = current; current = current.getNext(); } if (previous == null ) { head = node; } else { previous.setNext(node); } node.setNext(current); count++; modCount++;
}
有序列表的插入代码,在运行调试之后,报错位置在这里。
while ( comparableElement.compareTo(current.getElement()) > 0 && current != null )
这是一开始的错误代码。发现,在进行while判断的时候,是先进行compareTo的比较大小操作,而非判断current是否为空。所以,当current为空的时候,就直接出现了空指针异常。
所以只需要把两个条件相互颠倒一下即可。
代码托管
上周考试错题总结
上周没有进行考试,所以没有错题。
结对及互评
评分标准
- 博客中值得学习的或问题:
- 学习:在总结问题时有附上详细的图片,而我总是忘记截图,代码中出现的问题也能及时自己发现错误来源。
- 问题:教材学习内容总结不够详细。
- 代码中值得学习的或问题:无
- 基于评分标准,我给本博客打分:15分。得分情况如下:
- 正确使用Markdown语法(加1分):
- 模板中的要素齐全(加1分)
教材学习中的问题和解决过程, 一个问题加1分()
- 代码调试中的问题和解决过程, 一个问题加1分()
- 本周有效代码超过300分行的(加2分)
- 其他加分:
- 感想,体会不假大空的加1分
- 排版精美的加一分
- 进度条中记录学习时间与改进情况的加1分
- 有动手写新代码的加1分
- 课后选择题有验证的加1分
- 错题学习深入的加1分
- 点评认真,能指出博客和代码中的问题的加1分
- 结对学习情况真实可信的加1分
点评过的同学博客和代码
其他(感悟、思考等,可选)
最近学习的都是数据结构的知识,相对应的代码量也变得多了起来,作业和课堂实践也变多了。但是博客还是应该要认真完成,不忘初心,继续努力!
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 10000行 | 30篇 | 400小时 | |
第一周 | 155/200 | 2/2 | 20/20 | 初步掌握linux命令、java小程序和jdb调试 |
第二 三周 | 470/625 | 2/4 | 20/40 | 学会scanner定义的使用,类的定义 |
第四周 | 1444/2069 | 2/4 | 20/60 | 下载安装IDEA及其插件,学会TDD调试,编写测试代码 |
第五周 | 1917/3986 | 2/8 | 20/80 | 简单的学会客户端和服务器的编写 |
第六周 | 1324/5310 | 1/9 | 20/100 | Java封装,继承,多态 |
第七周 | 2795/8105 | 3/12 | 40/140 | 栈,链表 |
第八周 | 1135/9240 | 1/13 | 40/180 | 选择排序等各种排序,查找等 |