Algorithm 仅使用一个堆栈实现优先级队列

Algorithm 仅使用一个堆栈实现优先级队列,algorithm,data-structures,Algorithm,Data Structures,使用两个堆栈实现队列或优先级队列并不难 现在问题是 只使用一个堆栈来实现优先级队列怎么样 只使用一个堆栈来实现正常队列怎么样 甚至可能吗 p、 当然,如果需要,您应该使用除一个堆栈之外的常量额外空间否,不可能仅使用通过堆栈接口提供的方法(即仅使用push和pop方法)和常量额外空间。[1] 考虑尝试使用堆栈模拟队列 当排队时,如果我们简单地推到堆栈上,我们将得到另一个元素,我们需要做些什么才能到达队列的前面进行出列。很容易看出,一堆排队将使下一个排队不可能占用固定的空间,因为所有这些排队的元素都

使用两个堆栈实现队列或优先级队列并不难

现在问题是

  • 只使用一个堆栈来实现优先级队列怎么样
  • 只使用一个堆栈来实现正常队列怎么样
  • 甚至可能吗


    p、 当然,如果需要,您应该使用除一个堆栈之外的
    常量
    额外空间

    否,不可能仅使用通过堆栈接口提供的方法(即仅使用push和pop方法)和常量额外空间。[1]

    考虑尝试使用堆栈模拟队列

    当排队时,如果我们简单地推到堆栈上,我们将得到另一个元素,我们需要做些什么才能到达队列的前面进行出列。很容易看出,一堆排队将使下一个排队不可能占用固定的空间,因为所有这些排队的元素都需要弹出才能到达队列的前面。我们也可以从堆栈顶部将排队的元素放入一个固定数量的元素中,但这也没有多大帮助-它下面的元素需要先被排出来,所以我们遇到了相同的问题。尝试将排队的元素放在堆栈顶部的元素数超过常量的位置,当然会占用更多的空间

    现在考虑一个优先级队列,其中每个新项的优先级比队列中的所有项都低。这是简单队列的同义词,根据上面的参数,不能使用具有恒定空间的单个堆栈来模拟简单队列


    [1] :如果堆栈实现为数组或链表(通常是这样),那么当然可以使用这些功能,但我确信这不是您要问的。

    假设您将
    n
    元素推到堆栈上。现在您希望元素位于它的底部(如果您想要实现一个队列)。您需要额外的O(n)空间来保存其他
    n-1
    元素,以便访问底部的元素


    =>在您的约束条件下,仅使用堆栈接口方法,无法使用单个堆栈和常量空间实现队列。

    如果只允许标准堆栈操作(
    pop
    push
    ),则无法执行该任务,因为将项目排入队列意味着从堆栈中弹出所有项目,推送新项目,然后推送所有项目。如果使用固定时间,则无法弹出所有项目并使用
    O(1)
    内存跟踪它们

    假设您使用双向链表实现了一个堆栈,并允许使用
    reverse
    方法-这意味着您翻转了堆栈的顺序(链表的尾部成为尾部)

    现在,对于常规队列,您可以执行以下操作:

    排队
    -执行
    反向
    推送
    新项目,然后再次执行
    反向
    dequeue
    -执行
    pop

    注意:一旦允许
    反向
    操作,它就不再是标准堆栈


    优先级队列仍然不可能实现,即使您允许
    反向
    ,因为您在排队或退队时仍然需要执行各种比较,并且仍然会遇到没有空间存储要比较的项目的问题。

    这里有一个技术上正确的解决方案,但对你的目的来说几乎毫无用处

    我们使用队列(常规或优先级)的堆栈
    S
    。我们初始化
    S
    以容纳一个空队列。对于任何队列操作,我们查看
    S
    的顶部元素,并将队列操作应用于它。这样,
    S
    将只保存一个元素


    如果您认为堆栈“拥有”其所有元素的内存,那么这将使用堆栈外的零内存。

    可能,最有可能。效率低下?当然。@AlejandroLucena的表现在这里不是问题。但这真的有可能吗?最多只有一个堆栈具有恒定的空间?只要您保持堆栈的机制(只能删除第一项),我认为就没有办法模拟队列。