|
|
|
|
移动端

练习(2)

《数据结构与算法分析:Java语言描述(原书第3版)》第3章表、栈和队列,本章讨论最简单和最基本的三种数据结构。实际上, 每一个有意义的程序都将显式地至少使用一种这样的数据结构, 而栈则在程序中总是要被间接地用到, 不管我们在程序中是否做了声明。本节为本章的练习部分。

作者:冯舜玺/陈越 译来源:机械工业出版社|2016-04-13 18:05

年前最后一场技术盛宴 | 1月27日与京东、日志易技术大咖畅聊智能化运维发展趋势!


练习(2)

3.16 提供ListIterator的另一种方式是提供带有声明

的表, 它返回一个Iterator, 并被初始化至最后一项, 其中next和hasNext被实现成与迭代器向表的前端(而不是向后)推进一致。然后, 你可以通过使用程序

反向打印MyArrayList L。用这种思路实现ArrayListReverseIterator类, 让reverseIterator返回一个新构造的ArrayListReverseIterator。

3.17 修改MyArrayList类, 通过使用在3.5节对MyLinkedList所看到的那些技巧以提供严格的迭代器检测。

3.18 对MyLinkedList类, 通过分别调用私有的add、 remove、 getNode例程实现addFirst、 addLast、 removeFirst、 removeLast、 getFirst和getLast等方法。98

3.19 不用头节点和尾节点重写MyLinkedList类, 并描述该类和3.5节所提供的类之间的区别。

3.20 不同于我们已经给出的删除方法, 另一种是使用懒惰删除(lazy deletion)的删除方法。要删除一个元素, 我们只是标记上该元素被删除(使用一个附加的位(bit)域)。表中被删除和非被删除元素的个数作为数据结构的一部分被保留。如果被删除元素和非被删除元素一样多, 则遍历整个表, 对所有被标记的节点执行标准的删除算法。

a. 列出懒惰删除的优点和缺点。

b. 编写使用懒惰删除实现标准链表操作的相应例程。

3.21 用下列语言编写检测平衡符号的程序:

a.    Pascal(begin/end,(),[],{})

b.    Java(/* */,(),[],{ })

c.   解释如何打印出一个很可能反映可能原因的错误信息。

3.22 编写一个程序计算后缀表达式的值。

3.23 a. 写出一个程序, 将包含(,),+,-,*和/等符号的中缀表达式转换成后缀表达式。

b. 将取幂运算符添加到指令系统中。

c. 编写一个程序将后缀表达式转换成中缀表达式。

3.24 编写只用一个数组而实现两个栈的例程。这些例程不应该声明溢出, 除非数组中的每个单元都被使用。

3.25*a. 提出一种数据结构支持栈push和pop操作以及第三种操作findMin, 它返回该数据结构中的最小元素。所有操作均以O(1)最坏情形时间运行。

*b. 证明, 如果我们添加找出并删除最小元素的第4种操作deleteMin, 那么至少有一种操作必然花费Ω(logN)时间。(本题需要阅读第7章)

3.26 指出如何用一个数组实现三个栈结构。

3.27 在2.4节中用于计算斐波那契数的递归例程如果对N=50运行, 栈空间有可能用完吗?为什么?

3.28 双端队列(deque)是由一列项组成的数据结构, 对该数据结构可以进行下列操作:

push(x):  将项x插入到双端队列的前端。

pop():  从双端队列中删除前端项并将其返回。

inject(x):  将项x插入到双端队列的尾端。

eject():  从双端队列中删除尾端项并将其返回。

编写支持双端队列的例程,  其中每种操作均花费O(1)时间。

3.29 编写以倒序打印双链表的算法, 只使用常数的附加空间。本题意味着, 不能使用递归但可以假设该算法是一个表成员函数。99

3.30 a. 写出自调整表(self-adjusting list)的数组实现。在自调整表中, 所有的插入都在前端进行。自调整表添加一个find操作, 当一个元素被find访问时, 它就被移到表的前端而并不改变其余的项的相对顺序。

b. 写出自调整表的链表实现。

*c. 设每个元素都有其被访问的固定的概率pi。证明那些具有最高访问概率的元素都靠近表的前端。

3.31 使用单链表高效实现栈类, 不用头节点和尾节点。

3.32 使用单链表高效实现队列类, 不用头节点和尾节点。

3.33 使用循环数组高效实现队列类。

3.34 如果从某个节点p开始, 接着跟有足够数目的next链将把我们带回到节点p, 那么这个链表包含一个循环。p不必是该表的第一个节点。假设给你一个链表, 它包含N个节点; 不过N的值是不知道的。

a. 设计一个O(N)算法以确定该表是否包含有循环。你可以使用O(N)的额外空间。

*b. 重复(a)部分, 但是只使用O(1)的额外空间。(提示: 使用两个迭代器, 它们最初在表的开始处, 但以不同的速度推进。)

3.35 实现队列的一种方法是使用一个循环链表。在循环链表中, 最后一个节点的next链是链接到第1个节点上的。假设该表不包含表头, 并假设我们最多可以保留一个迭代器, 它对应表中的一个节点。对于下列的哪种表示方式, 所有的基本队列操作都可以以常数最坏情形时间执行?证明你的答案是正确的。

a. 保留一个迭代器, 它对应该表的第一项。

b. 保留一个迭代器, 它对应该表的最后一项。

3.36 设我们有到单链表的一个节点的引用, 而且保证它不是该表的最后的节点。我们没有到任何其他节点的引用(除非通过后面的一些链)。描述一个O(1)算法, 该算法逻辑上从该链表删除存储在这样一个节点上的值, 同时保持链表的完整性。(提示: 涉及下一个节点。)

3.37 设单链表用到一个头节点和一个尾节点来实现。描述下述操作的常数时间算法:

a. 在位置p(由一个迭代器给出)前插入一项x。

b. 删除存储在位置p(由一个迭代器给出)的项。


喜欢的朋友可以添加我们的微信账号:

51CTO读书频道二维码


51CTO读书频道活动讨论群:342347198

【责任编辑:book TEL:(010)68476606】

回书目   上一节   
点赞 0
分享:
大家都在看
猜你喜欢

读 书 +更多

JSP应用开发详解(第三版)

本书结合JSP和Servlet的最新规范,从基本的语法和规范入手,以经验为后盾,以实用为目标,以实例为导向,以实践为指导,深入浅出地讲解了JS...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊