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

时间:2011-02-02 10:47:46

标签: algorithm

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

大家,这是一个面向软件工程师/开发人员的微软面试问题。我只是无法弄明白问题的含义。所以我很好地发现了这个:

可以将堆栈和队列建模为特定类型的优先级队列。在堆栈中,每个插入元素的优先级是单调递增的;因此,插入的最后一个元素始终是第一个被检索的元素。

所以这个问题要我们做什么。作为堆栈(纠正我,如果错了)隐式实现为优先级队列(优先级随着元素的添加而单调递增)。

有没有人可以弄清楚这个问题的含义。在面试中提出这类问题时我们该怎么做。

7 个答案:

答案 0 :(得分:20)

伪代码:

// stack of Key
class Stack {
    class Element { int prio, Key elem; };
    MaxPriorityQueue<Element> q;
    int top_priority = 0;

    void push(Key x) { q.push(Element(top_priority++, x)); }
    Key pop() { top_priority--; return q.pop().elem; }
};

LIFO的行为源于这样一个事实:每个新元素的优先级都高于所有当前元素,因此它将在任何元素之前弹出。

有两种方式可以回答这个面试问题。一个是详细解释上面的结构。第二个是简单地提一下,嘟about一些关于O(lg n )的东西,并说你永远不会以这种方式实现堆栈。

答案 1 :(得分:6)

如果您不知道优先级队列是什么,请询问。如果您不知道堆栈是什么,请询问。如果你不明白这个问题,请问。到目前为止,您应该能够确定需要如下所示的适配器。

Stack :
    private:
      q : MaxPriorityQueue
      counter : 0

    public:
      push(x) : q.add(x, counter++)
      pop() : q.remove()

答案 2 :(得分:2)

这些问题需要你思考一下(虽然不是很深)。

对此答案的解释是,不应将每个元素的值作为键插入,而应将它们包装到Object中,并将 order 指定为属性。你应该把这个命令作为关键。

示例C代码:

struct MyNode
{
  DataPacket dataPacket;
  int order;
};

答案 3 :(得分:2)

以下是此问题的java实现。

public class StackPriorityQueue {

PriorityQueue<StackElement> queue = new PriorityQueue<>(10, new Comparator<StackElement>() {
    @Override
    public int compare(StackElement o1, StackElement o2) {
        return o2.key - o1.key;
    }
});

int order = 1;

public void push(int val){
    StackElement element = new StackElement(order++,val);
    queue.add(element);
}

public Integer pop(){
    if(queue.isEmpty()){
        System.out.println("Stack Underflow");
        return null;
    }
    return queue.poll().value;
}

public static void main(String... args){
    StackPriorityQueue q = new StackPriorityQueue();
    q.push(5);
    q.push(10);
    q.push(1);
    q.push(3);
    q.push(50);
    q.push(500);
    q.push(60);
    q.push(30);
    q.push(40);
    q.push(23);
    q.push(34);

    System.out.println(q.pop());
    System.out.println(q.pop());
    System.out.println(q.pop());
    System.out.println(q.pop());
    System.out.println(q.pop());
    System.out.println(q.pop());
    System.out.println(q.pop());
    System.out.println(q.pop());
    System.out.println(q.pop());
    System.out.println(q.pop());
    System.out.println(q.pop());
    System.out.println(q.pop());

   }

}

class StackElement {
  int key;
  int value;

  public StackElement(int key, int value) {
    this.key = key;
    this.value = value;
  }

}

答案 4 :(得分:0)

具有时间复杂性和空间复杂性的Java实现:

时间复杂度:Java优先级队列是使用堆数据结构实现的,并且堆具有O(log(n)),插入元素的时间复杂度。

空间复杂度:O(2k),用于将元素存储在“优先级队列”中及其相关顺序。

public class StackUsingHeap {

public static void main(String[] args) {

    Stack stack = new Stack();
    stack.push(10);
    stack.push(15);
    stack.push(20);

    System.out.println(stack.pop());
    System.out.println(stack.pop());
    System.out.println(stack.pop());
}
}

class Stack {

    PriorityQueue<Node> pq = new PriorityQueue<>(new Node());
    static int position = -1;

    public void push(int data) {
      pq.add(new Node(data, ++position));
   }

   public int pop() {
     --position; // optional
     return pq.remove().data;
   }
  }

 class Node implements Comparator<Node> {

   int data;
   int position;

   public Node() {
   }

   public Node(int data, int position) {
    this.data = data;
    this.position = position;
  }

  @Override
  public int compare(Node n1, Node n2) {
    if (n1.position < n2.position)
        return 1;
    else if (n1.position > n2.position)
        return -1;
    return 0;
  }
 }

答案 5 :(得分:0)

这是此问题的Java实现。

import org.junit.Test;

import java.util.PriorityQueue;

import static org.junit.Assert.assertEquals;

public class StackHeap {
    @Test
    public void test() {
        Stack s = new Stack();
        s.push(1);
        s.push(2);
        s.push(3);
        assertEquals(3, s.pop());
        assertEquals(2, s.pop());
        s.push(4);
        s.push(5);
        assertEquals(5, s.pop());
        assertEquals(4, s.pop());
        assertEquals(1, s.pop());
    }

    class Stack {
        PriorityQueue<Node> pq = new PriorityQueue<>((Node x, Node y) -> Integer.compare(y.position, x.position));
        int position = -1;

        public void push(int data) {
            pq.add(new Node(data, ++position));
        }

        public int pop() {
            if (position == -1) {
                return Integer.MIN_VALUE;
            }
            position--;
            return pq.poll().data;
        }
    }

    class Node {
        int data;
        int position;
        public Node (int data, int position) {
            this.data = data;
            this.position = position;
        }
    }
}

答案 6 :(得分:-1)

您可以使用 min heap 使用优先级队列(比如PQ)来实现堆栈。您需要一个额外的整数变量(比如说t)。插入/删除PQ中的元素时,' t '将用作优先级。

你必须在开始时初始化t (比如说t = 100)到某个值。

push(int element){
PQ.insert(t,element);
t--;           //decrease priority value(less priority will be popped first)
}

pop(){
return PQ.deleteMin();
}

peek(){
return PQ.min();
}

注意:您还可以使用系统时间根据优先级推送元素。

push(int element){
PQ.insert(-getTime(),element);   //negative of sys time(less priority will be popped first)
}