|
|
|
|
移动端

练习(2)

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

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

技术沙龙 | 邀您于8月25日与国美/AWS/转转三位专家共同探讨小程序电商实战

练习(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邮刊