【问题标题】:Adding,deleting and inserting elements in O(logn)在 O(logn) 中添加、删除和插入元素
【发布时间】:2015-05-04 07:21:45
【问题描述】:

我们被要求创建一个在 O(logn) 的最坏情况下运行的算法

算法由3个函数组成:getmin();getmax();add();

首先从栈中弹出最小的元素,并返回它; getmax 从堆栈中弹出最大的元素并返回它; 在堆栈上添加 put 元素。

我在想一棵 RB 树;但我意识到我自己很难实现(从零开始)。

是否存在其他实现起来不太复杂且运行时间为 O(logn) 的树或数据结构?

我只能使用基本的 python 操作(即只有列表,..)

【问题讨论】:

  • 经典的实现方式是heaps
  • @cfh 你将如何实现一个同时支持删除最小值和最大值的堆?
  • 这不是您问题的答案,但您可以通过维护另一个临时堆栈来获取 O(1) 中的最小值,该堆栈将保存当前最小值的参考,类似地可以这样做以获得最大值。
  • 保持你的“堆栈”有序;您可以在O(log n) 中对add 使用二分法,得到最小值或最大值变为O(1)(忽略底层列表性能)。

标签: python algorithm data-structures


【解决方案1】:

我建议Treap。在我看来,它是最容易实现的平衡二叉搜索树,因为您只需要 2 次基本旋转。

要搜索给定的键值,请在二叉搜索树中应用标准二叉搜索算法,忽略优先级。

要将新密钥 x 插入到 treap 中,请为 x 生成随机优先级 y。在树中对 x 进行二分搜索,并在二分搜索确定应存在 x 的节点的叶子位置处创建一个新节点。然后,只要 x 不是树的根并且具有比其父 z 更大的优先级数,就执行树旋转,反转 x 和 z 之间的父子关系。

要从树中删除节点 x,如果 x 是树的叶子,只需将其删除。如果 x 有一个子 z,则从树中删除 x 并使 z 成为 x 的父级的子级(如果 x 没有父级,则使 z 成为树的根)。最后,如果 x 有两个孩子,则将其在树中的位置与其直接后继 z 的位置按排序顺序交换,从而导致上述情况之一。在最后一种情况下,交换可能会违反 z 的堆排序属性,因此可能需要执行额外的轮换来恢复此属性。

可以通过从根一直向左移动以获得最小值,一直向右移动以获得最大值来获得最小值和最大值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-21
    • 1970-01-01
    • 1970-01-01
    • 2016-12-27
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多