算法分析与设计 - 作业1

问题一

给栈结构设计一个求最小值的操作,要求入栈、出栈以及求最小值均在 \(O(1)\) 完成。

考虑对栈 \(s\) 额外维护一个辅助栈 \(s'\),自底向上的第 \(i\) 个元素为栈 \(s\) 中自底向下前 \(i\) 个元素中的最小值,则查询 \(s\) 中最小值操作即为查询 \(s'\) 栈顶元素。

考虑在维护 \(s\) 的同时维护 \(s'\):元素 \(v\) 入栈 \(s\) 时,将 \(s'\) 栈顶元素与 \(v\) 中较小值入栈 \(s'\)\(s\) 出栈时同时将 \(s'\) 出栈即可。

只是新增了一个与原栈空间相同的栈,则空间复杂度仍为 \(O(n)\) 级别,上述所有操作仅涉及常数次比较与入出栈操作,时间复杂度为 \(O(1)\) 级别。

问题二

给出策略利用栈去完成一个序列的排序,并分析相应的性能。

在问题一中给出了查询栈中最小值的实现方法,考虑实现一个类似选择排序的算法,在使用栈维护无序部分,不断地取出此时栈中的最小值并放入有序部分的尾部。

该算法的进行需要额外维护一个用来暂存元素的栈 \(s''\)。具体地:

  1. 首先将序列中所有元素按顺序入栈。
  2. 将此时栈中最小值 \(v'\) 出栈,并放入有序部分的尾部。
  3. 不断对 \(s\) 进行出栈操作,并将出栈的元素入栈 \(s''\) 中,直至栈 \(s\) 的栈顶元素为 \(v'\)
  4. 进行一次出栈操作将 \(v'\) 出栈,再不断地对 \(s''\) 进行出栈操作直至栈空,并将出栈元素入栈 \(s\) 中。
  5. 重复上述步骤 2~4 直至栈空,即可求得有序序列。

需要进行 \(n\) 次取出最小值操作,每次取出最小值时都需要不断出栈直至当前栈顶为最小值再进行入栈,元素比较与出入栈操作次数上限为当前栈的大小,则总时间复杂度为 \(O(n^2)\) 级别,当待排序序列单调递增(已为有序状态)时可达到时间复杂度上限。

维护了三个栈与用于存储有序部分的数据结构,元素数量总和为序列长度的常数倍,空间复杂度 \(O(n)\) 级别。

posted @ 2024-03-18 13:05  Rainycolor  阅读(29)  评论(0)    收藏  举报