📜  如何使用优先队列或堆实现堆栈?

📅  最后修改于: 2021-10-28 01:59:05             🧑  作者: Mango

如何使用优先级队列(使用最小堆)实现堆栈?。

问:微软,Adobe。

解决方案:

在优先级队列中,我们为正在推送的元素分配优先级。堆栈要求以后进先出方式处理元素。这个想法是关联一个决定何时推送的计数。此计数用作优先级队列的键。

所以堆栈的实现使用了一个优先级对队列,第一个元素作为键。

pair  (key, value)

请参阅下图以更好地理解

下面是这个想法的 C++ 实现。

// C++ program to implement a stack using
// Priority queue(min heap)
#include
using namespace std;
  
typedef pair pi;
  
// User defined stack class
class Stack{
      
    // cnt is used to keep track of the number of
    //elements in the stack and also serves as key
    //for the priority queue.
    int cnt;
    priority_queue > pq;
public:
    Stack():cnt(0){}
    void push(int n);
    void pop();
    int top();
    bool isEmpty();
};
  
// push function increases cnt by 1 and
// inserts this cnt with the original value. 
void Stack::push(int n){
    cnt++;
    pq.push(pi(cnt, n));
}
  
// pops element and reduces count.
void Stack::pop(){
    if(pq.empty()){ cout<<"Nothing to pop!!!";}
    cnt--;
    pq.pop();
}
  
// returns the top element in the stack using
// cnt as key to determine top(highest priority),
// default comparator for pairs works fine in this case 
int Stack::top(){
    pi temp=pq.top();
    return temp.second;
}
  
// return true if stack is empty
bool Stack::isEmpty(){
    return pq.empty();
}
  
// Driver code
int main()
{
    Stack* s=new Stack();
    s->push(1);
    s->push(2);
    s->push(3);
    while(!s->isEmpty()){
        cout<top()<pop();
    }
}

输出:

3
 2
 1

现在,正如我们所看到的,这个实现对于 push 和 pop 操作都需要 O(log n) 时间。这可以通过使用优先队列的斐波那契堆实现稍微优化,这会给我们 O(1) 推送操作的时间复杂度,但 pop 仍然需要 O(log n) 时间。

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。