20172316 2017-2018-2《程序设计与数据结构》第十周学习总结
教材学习内容总结
- 第十三章:集合
由于这一周直接进行了链表的插入和删除限时作业,这一实践大大地加快了我们对教材内容的理解。
- 集合和数据结构:提到了ArrayList类就是一个集合,所以我就简单的理解为:我做一个集合
--> 我做一个和ArrayList类作用差不多的类
--> 我做一个保存指定类型的ArrayList类 - 集合的同构与异构:如上所述,同构的集合只能保存类型相同的对象;异构的如ArrayList就可以保存不同的对象,主要基于继承机制和多态性。
书中一句话我认为出现了翻译不到位的地方:
ArrayList储存的是对象的引用
不通顺,应该是ArrayList储存的是Object(类)的引用。
-
数据结构的动态表示:这里可以看到ArrayList类和我们这章要做的并不一样,这也是为什么我之前强调“作用差不多”,其结构从结构角度上来说只是半个动态的,不太高效。
-
动态连接的列表:emmm,就是我们在蓝墨云上做的那个吧。
-
其他的动态列表:除了我们做的单向链表,还有双向链表,其最后节点的
next
和最前节点的prev
(头节点)都是null
,向前向后访问时较方便,但建立、修改链表较为复杂。 -
至于线性数据结构,其中最重要的应该是栈,现在才看到这里真是“相见恨晚”,当时四则运算项目开始进行前就看到了就会轻松一点点了。
-
非线性,略
教材学习中的问题和解决过程
由于上课老师讲课时睡着了(认错),一觉醒来就要求做作业,但对于链表的知识是亿脸懵逼,node
next
list
究竟是什么呢? 参考了一下文章数据结构(一) 单链表的实现-JAVA
head为头节点,他不存放任何的数据,只是充当一个指向链表中真正存放数据的第一个节点的作用,而每个节点中都有一个next引用,指向下一个节点,就这样一节一节往下面记录,直到最后一个节点,其中的next指向null。
单看书中的图片比较抽象,文字结合图片来看一目了然。
再对照书中的和文章中的代码
public void addNode(Node node){
//链表中有结点,遍历到最后一个结点
Node temp = head; //一个移动的指针(把头结点看做一个指向结点的指针)
while(temp.next != null){ //遍历单链表,直到遍历到最后一个则跳出循环。
temp = temp.next; //往后移一个结点,指向下一个结点。
}
temp.next = node;
public void add(Magazine mag) {
MagazineNode node = new MagazineNode(mag);
MagazineNode current;
if (list == null)
{
list = node;
}
else {
current = list;
while (current.next != null)
{current = current.next;}
current.next = node;
}
}
head == list。这再看不懂就没道理了。temp.next
就是指temp
的下一个节点,指针的运用很重要。
代码调试中的问题和解决过程
- 问题1:做PP13.1时偶然间发现,一个相同的对象在可以同时出现在链表中两次,但排序之后其中一次被消除。
这样的问题并不是什么大问题,但是如果有地方要用到“一个对象出现两次”,结果被消除了(是在玩消消乐吗?)那该如何是好?
- 问题1解决方案:
从根源入手,看排序方法(选择排序法)的代码:
public void Sort() {
DVD temp; //缓存
if (list.dvd.compareTo(list.next.dvd) > 0) {
temp = list.next.dvd;//如果前一个比后一个大
list.next.dvd = list.dvd;//缓存=后一个,后一个=前一个,
list.dvd = temp;//前一个=缓存
}
DVDNode temp1 = list;
DVDNode temp2;
while (temp1.next != null) {
temp2 = temp1.next;
while (temp2.next != null) {
if (temp1.next.dvd.compareTo(temp2.next.dvd) > 0) {
temp = temp2.next.dvd;
temp2.next.dvd = temp1.next.dvd;
temp1.next.dvd = temp;
}
temp2 = temp2.next;
}
temp1 = temp1.next;
}
}
为何会消失,排序时使用选择排序法,肯定有变量遇到自己的一瞬间,就像如果我走在街上遇到一个和自己长的一摸一样的人,我会拿自己和他(它?)比较,即compareTo()
,再深入一点,我的compareTo
方法是:
public int compareTo(DVD mag) {
int i = 0;
int a = 0;
while (title.charAt(i) == mag.toString().charAt(i)) {
i++;
}
if ((int) (title.charAt(i)) < (int) (mag.toString().charAt(i)))
{a = -1;}
else
{a = 1;}
return a;
}
只比较了title
,比较懒,不过也使检查简单了许多,而且变量的title
就一个字母,这里没有问题,比较过程也就是compareTo
的结果就是(int) 0
。
回到Sort()
,哪里出了问题,啊啊啊啊啊啊,我用什么让另一个自己消失呢?在同一时空不可能出现两个自己,一个人不可以和自己相遇,这就是有名的时间悖论,
灵光一闪!想到了删除(delete()
)的原理:magazine类的删除方法
public void delete(Magazine mag) {
MagazineNode node = list;
while (node.next.magazine != mag) {
node = node.next;
}
node.next = node.next.next;
}
删除一个对象就是让temp = temp.next.next
,也就是让中间需要被删除的节点空出来。当节点排序到自己前时,temp == temp.next
,两段同时加上.next
,temp.next == temp.next.next
???与事实不符出现悖论!!!震惊!!!我用Java的单链表证明了单向流动的时间中所出现的时间悖论!!!所以问题解决了。为了避免这种无解的问题出现,遇到这种情况,由于两者是同一对象,当自己是自己的next时,就会自动合并了,这相当于出现时间悖论时,时间线自动收束,两个自己合为一个自己,其中一个并入了另一个的时间线,再也不会出现。
强行扯物理的关系,感觉自己的物理和JAVA都白学了
代码托管
(statistics.sh脚本的运行结果截图)
上周考试错题总结
- 错题1: A recursive method without a base case leads to infinite recursion.
正确答案:A .true
原因:书上有原话,但是看书本不仔细,没记住:
请记住,列表的定义包括非递归定义和递归定义两部分。非递归部分称为基本情况。如果只有递归部分定义的那一部分,则递归将永无终止。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 195/195 | 1/4 | 20/20 | 对代码产生了很大兴趣 |
第二周 | 309/504 | 1/5 | 20/40 | 打字速度明显提升 |
第三周 | 311/815 | 2/7 | 25/65 | 无 |
第四周 | 474/1289 | 1/8 | 30/95 | 抗...抗压能力加强? |
第五周 | 260/1549 | 1/9 | 15/110 | 了解到预习的重要性 |
第六周 | 358/1907 | 2/11 | 20/130 | 打字速度明显提升 |
第七周 | 780/2687 | 2/13 | 15/145 | 学会使用JUnit |
第八周 | 2124/4811 | 2/10 | 15/160 | 无 |
第九周 | 967/5778 | 2/12 | 20/180 | 递归思想的利用 |
第十周 | 1047/6855 | 2/14 | 25/205 | 初步接触数据结构 |
结对互评
唐才铭19:博客中图片很多,有助于阅读理解,也有可能太多了(可能是尺寸较大的缘故);MarkDown格式出现部分失误,可简单修改。
王文彬29:第一次使用表情包,这很好;上次遇到过的问题解决得不够彻底,这次的代码问题1不应该再次出现。
参考资料
- 《Java程序设计教程(第八版)》电子工业出版社
- 《使用码云和博客园学习简易教程》
- 《使用开源中国(码云)托管代码》
- 数据结构(一) 单链表的实现-JAVA