如何使用优先级队列实现堆栈?
大家,这是一个面向软件工程师/开发人员的微软面试问题。我只是无法弄明白问题的含义。所以我很好地发现了这个:
可以将堆栈和队列建模为特定类型的优先级队列。在堆栈中,每个插入元素的优先级是单调递增的;因此,插入的最后一个元素始终是第一个被检索的元素。
所以这个问题要我们做什么。作为堆栈(纠正我,如果错了)隐式实现为优先级队列(优先级随着元素的添加而单调递增)。
有没有人可以弄清楚这个问题的含义。在面试中提出这类问题时我们该怎么做。
答案 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)
}