数据结构笔记浅记(十二) 双向队列

链表或数组作为底层数据结构

双向链表的头节点和尾节点视为双向队列的队首和队尾,同时实现在两端添加和删除节点的功能

使用环形数组来实现双向队列

双向队列应用

双向队列兼具栈与队列的逻辑,因此它可以实现这两者的所有应用场景,同时提供更高的自由度。 我们知道,软件的“撤销”功能通常使用栈来实现:系统将每次更改操作 push 到栈中,然后通过 pop 实现撤销。然而,考虑到系统资源的限制,软件通常会限制撤销的步数(例如仅允许保存 50 步)。当栈的长度超过 50 时,软件需要在栈底(队首)执行删除操作。但栈无法实现该功能,此时就需要使用双向队列来替代栈。请 注意,“撤销”的核心逻辑仍然遵循栈的先入后出原则,只是双向队列能够更加灵活地实现一些额外逻辑。

 

Q:浏览器的前进后退是否是双向链表实现?

浏览器的前进后退功能本质上是“栈”的体现。当用户访问一个新页面时,该页面会被添加到栈顶;当用户 点击后退按钮时,该页面会从栈顶弹出。使用双向队列可以方便地实现一些额外操作。

Q:在出栈后,是否需要释放出栈节点的内存?

如果后续仍需要使用弹出节点,则不需要释放内存。若之后不需要用到,Java 和 Python 等语言拥有自动垃圾回收机制,因此不需要手动释放内存;在 C 和 C++ 中需要手动释放内存。

Q:双向队列像是两个栈拼接在了一起,它的用途是什么?

双向队列就像是栈和队列的组合或两个栈拼在了一起。它表现的是栈 + 队列的逻辑,因此可以实现栈与队列 的所有应用,并且更加灵活。

Q:撤销(undo)和反撤销(redo)具体是如何实现的?

使用两个栈,栈 A 用于撤销,栈 B 用于反撤销。

        1. 每当用户执行一个操作,将这个操作压入栈 A ,并清空栈 B 。

         2. 当用户执行“撤销”时,从栈 A 中弹出最近的操作,并将其压入栈 B 。

        3. 当用户执行“反撤销”时,从栈 B 中弹出最近的操作,并将其压入栈 A 。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章