笨办法学 Python · 续 练习 15:栈和队列

练习 15:栈和队列

原文:Exercise 15: Stacks and Queues

译者:飞龙

协议:CC BY-NC-SA 4.0

自豪地采用谷歌翻译

当处理数据结构时,你将经常遇到类似于另一种结构的结构。Stack类似于练习13中的SingleLinkedList,以及Queue类似于练习14中的DoubleLinkedList,唯一区别是StackQueue限制了可能的操作,以简化它们的使用方式。这有助于减少缺陷,因为你不能意外地像Queue那样使用Stack并导致问题。在Stack中,节点被“压入”“栈顶”,然后从顶部“弹出”。在队列中,节点压入“尾部”,之后从“头部”弹出。这些操作都是SingleLinkedListDoubleLinkedList的简化,其中Stack只允许pushpop操作,Queue只允许shiftunshift

译者注:实际上是pushunshift

当可视化堆栈时,你应该想到你的地板上的一堆书。想像我在书架上的那种很重的艺术书,如果我堆叠了20个,可能会重约100磅。当你为这些书构建栈的时候,你不能抬起整个栈,并且把书放在底部,对吧?不,你把书放在栈的顶部。你把它放在那儿,但我们也可以使用“推”描述这个动作。如果你想从栈中获取一本书,你可能会抬起一些书,然后抓住一本书,但是最终你可能要从顶部拿出一些书,才能获取底部得数。你可以从顶部抬起每本书,或者在我们的例子中,我们会说“从顶部弹出一本书”。

如果你想像在银行排队,队列有“头部”和“尾部”,可视化队列是最简单的。通常有一个绳索迷宫,它的末尾有一个入口,出口处是检票员。你可以通过进入这条绳索迷宫的“尾部”进入队列,我们​​称之为shift,因为这是Queue数据结构中的常见编程属于。一旦你进入银行(队列),你不能越过等候线然后离开,否则其余的人会生气。所以你必须等待,随着你前面的每个人都离开了等候线(对你而言是unshift),你离“头部”更近了。一旦你达到了头部,那么你可以退出,我们称之为unshift

很多时候,你可以找到数据结构的真实世界示例,来帮助你可视化其工作原理。你现在应该花点时间来绘制这些场景,或者实际上得到书籍的栈并测试这些操作。你可以找到与StackQueue类似的其他真实情况吗?

挑战练习

我现在打算让你做一个基于代码的挑战练习,并且从它们的描述中实现数据结构。在这个挑战中,你首先需要使用这里的起始代码,以及你从练习 13 中了解的SingleLinkedList,实现Stack数据结构。完成之后,你将尝试从零开始实现Queue数据结构。

StackNode节点类几乎和SingleLinkedListNode相同,而事实上我只是复制过来并更名:

class StackNode(object):

    def __init__(self, value, nxt):
        self.value = value
        self.next = nxt

    def __repr__(self):
        nval = self.next and self.next.value or None
        return f"[{self.value}:{repr(nval)}]"

Stack控制类和SingleLinkedList十分类似,除了我使用top代替了first。这样匹配Stack的概念。

class Stack(object):

    def __init__(self):
        self.top = None

    def push(self, obj):
        """Pushes a new value to the top of the stack."""

    def pop(self):
        """Pops the value that is currently on the top of the stack."""

    def top(self):
        """Returns a *reference* to the first item, does not remove."""

    def count(self):
        """Counts the number of elements in the stack."""

    def dump(self, mark="----"):
        """Debugging function that dumps the contents of the stack."""

现在你的挑战是实现Stack,并为其执行测试,类似于在练习 13 中进行的测试。请确保你的测试涵盖了每一个操作,你可以以任何方式。记住,尽管如此,堆栈的push操作必须在顶部,所以有到顶部的链接。

一旦你使Stack正常工作,你应该实现Queue,但它基于DoubleLinkedList。(译者注:其实单链表也行,因为只有尾部弹出的操作比较困难。你可以在尾部插入,在头部弹出。)Stack中的内容应该与SingleLinkedList基本内部结构相同,只需更改允许的功能。Queue也一样。花点时间来绘制队列的工作原理,然后弄清楚它如何限制DoubleLinkedList。一旦你完成了,创建你的队列。

破坏它

破坏这些数据结构仅仅是不要维持约束。看看如果一个操作无法使用正确的尾部会发生什么。

你可能还注意到,它有“偏移一位”的持久性错误。在我的设计中,当结构为空时,我设置了self.top = None。这意味着当你达到 0 个元素时,你必须对self.top做一些特殊处理。一个替代方法是使self.top总是指向一个StackNode(伪造的头节点),并假设当你有这个最后的元素时,结构是空的。尝试它,看看它如何改变你的实现。这样会更容易出错还是更不容易出错?

深入学习

这些数据结构有很多操作是非常低效的。回顾你为每个数据结构编写的代码,并尝试猜测哪些函数最慢。一旦你有了想法,尝试解释为什么他们可能很慢。研究其他人对这些数据结构的看法。在练习 18 和 19 中,你将学习对这些数据结构进行一些性能分析并进行调整。

最后,你真的需要实现一个全新的数据结构吗,还是简单地“包装” SingleLinkedListDoubleLinkedList数据结构?这如何改变你的设计?

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容

  • 栈 栈的英文单词是Stack,它代表一种特殊的线性表,这种线性表只能在固定一端(通常认为是线性表的尾端)进行插入,...
    Jack921阅读 1,492评论 0 5
  • 练习42:栈和队列 原文:Exercise 42: Stacks and Queues 译者:飞龙 到现在为止,你...
    布客飞龙阅读 500评论 0 36
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,442评论 25 707
  • 细雨太湖白,轩窗任意开。朦胧江左秀,水墨画中来。 注:江左即江南。 图原创 文原创
    深谷留风阅读 329评论 13 24
  • 最近笑来老师的天天用英语在搞年中复盘,我想了想,投不投稿先放一边,要不自己趁着这个机会也盘点盘点这半年的英语学习情...
    JYQC66阅读 1,851评论 0 0