20172301 《程序设计与数据结构》第三周学习总结
20172301 《程序设计与数据结构》第三周学习总结
教材学习内容总结
- 队列
- 队列是一种线性集合,先进先出。
- 元素一般从队列末端进入,从队列前端退出。
- 在栈中,处理过程只在栈的一端进行;在队列中,处理过程在队列的两端进行。
- API中的队列
- Stack类实现了栈集合。却没有队列类。只提供了 Queue接口
- Stack类提供了基本操作。Queue接口只定义了两种方法,添加元素和删除元素。
- 使用队列:代码密钥(书上代码杂乱无章)
详见教材问题二。戳 - 用链表实现队列:
- 在enqueue操作,在链表前端添加新结点,就把新结点的next指针设置为指向链表的head变量,把head变量设置为指向新结点。复杂度为O(1)。
- 在enqueue操作,在链表末端添加新结点,就把链表末端结点的next指针设置为指向新结点,然后把链表的tail设置为指向新结点。复杂度为O(1)。
- 在dequeue操作,在链表前端,设置一个临时变量指向链表前端的元素,然后把front变量设置为第一个结点的next指针的值。复杂度为O(1)。
- 在dequeue操作,在链表末端,复杂度为O(n)
- 对于单向链表,可选择从末端入列,从前端出列。对于双向链表,无所谓从哪端入列和出列。
- 用数组实现队列:
- 将队列的某一端固定在数组的索引0处。所有元素会不间断地存放在数组中。
- 非环形数组实现的元素移位,将产生O(n)的复杂度。
- 用固定数组来实现队列的效率不高。
教材学习中的问题和解决过程
-
问题1:Queue接口两种方法add和offer在异常类处理上有何不同。
-
问题1解决方案:
根据书上所说- add操作可以确保队列中有给定的元素。如果给定元素没有添加到队列中,该操作将抛出一个异常。
- offer操作把给定元素插入到队列中,如果插入成功,返回true,否则返回false。
查询API所得,
也就是书上说的一个是提供了一个布尔返回值,另一个则是抛出一个异常。
那么add方法和offer方法有何不同?
区别:两者都是往队列尾部插入元素,不同的时候,当超出队列界限的时候,add()方法是抛出异常让你处理,而offer()方法是直接返回false。 -
问题2:书上用队列实现代码密钥,代码的相关理解。
-
问题2解决过程:
-
创建一个数组,录入密钥值;
-
把密钥值分别存放到两个单独队列中。编码者使用一份密钥,解码者使用另一个密钥。
-
通过循环,把字母移动相对应的密钥的数位,形成新的字符。
根据其在ASCII表中的位置,相对应的移动几位,形成新的字符。 -
输出加密和解密后字符串。
-
注意:密钥在此程序中循环重复使用。
encodingQueue.add(keyValue);
比如密钥是{5,12,-3,8,-9,4,10}
一次循环返回后即是{12,-3,8,-9,4,10,5}
同样,可以编码任何字符 -
代码调试中的问题和解决过程
-
问题1:PP5.7的实现设计思路。
-
问题1解决方案:
- 双端队列的实现很容易结合第二章所学的双向链表的相关知识。我们一般需要维护两个引用:一个引用指向链表的首节点,我定义为
front
;另一个引用指向链表的末结点,我定义为rear
。同时,链表中的每个结点都应该存有两个引用。一个指向上一个元素,一个指向下一个元素。所以,我们需要重新定义一个结点类。 - 如何处理接口问题?
- 这里我首先根据书上的内容查询了API Deque接口,发现其中包含许多栈和队列的操作和方法。
我们这里并不需要涉及全部,我认为只需要基本的头插,尾插,头删,尾删,以及返回个数,返回顶端,toString的基本操作。 - 这里可能有人会说双端队列和双端链表并不相同,不可以直接类比。
- 经过我的查询呢,双端队列和双端链表确实有所区别。队列只能对头尾两个元素操作。双向队列头尾均可插入,弹出;双向链表则可以从任何一个元素位置起找到其他所有元素。但是呢,其实这两个没有什么比较的意义。我也只是类比其设计的思路。
- 对比单向链表的LinkedQueue,具体的方法实现便不再赘述。
- 双端队列的实现很容易结合第二章所学的双向链表的相关知识。我们一般需要维护两个引用:一个引用指向链表的首节点,我定义为
-
问题2:书P89 dequeue操作代码中
public T dequeue() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException("queue");
T result = queue[front];
queue[rear] = null;
front = (front+1) % queue.length;
count--;
return result;
}
测试类中,总是删除队尾的元素。
- 问题2 的解决方案:
正常来说,队列应该是从末端进,首端出。但是,我测试dequeue操作却删除了尾端的元素。
这个其实是书上代码的错误。应该是queue[front] = null
意思是把队列首端设置为空。这里的队列首端并不固定在数组的0索引处,所以也不能通过删除索引0的元素来达到dequeue的操作。
代码托管
一些接口在jsjf文件夹中。
上周考试错题总结
- 上周无测试
结对及互评
- 上周博客互评情况
其他
尽信书则不如无书。新的java教材有很多翻译不恰当和代码问题,在对书上内容的理解上会有很大的偏差。但是我们无法改变书本的好坏,与其抱怨,只能多花时间明白其错误在哪里,杜绝掉其中的代码错误,因为往往是因为一个变量错误,结果就是千差万别。所以,注意细节,是每个程序员必备的觉悟和素质。代码如此,人亦如此。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 0/0 | 1/1 | 10/10 | |
第二周 | 610/610 | 1/2 | 20/30 | |
第三周 | 593/1230 | 1/3 | 18/48 |
补充作业
目前水平(0~9) | 课程结束后水平(0~9) | |
---|---|---|
程序理解 | 3 | 8 |
代码规范/质量 | 5 | 9 |
单元测试/代码覆盖率 | 4 | 8 |
模块实现/逐步细化 | 5 | 9 |
自主学习能力 | 6 | 8 |
协同工作 | 5 | 9 |
现阶段,代码的理解和实现使我们需要提高的关键。更好的理解书上的代码可以帮助我们应用更多的场景模式。而代码实现的质量则需要日渐积累,这不是一蹴而就的。细节的成败,同样是影响代码的质量,这更应该使我们所要避免的。我们应该对我们编写的每一份代码负责。 |