我正在使用带有标记的双向链表编写优先级队列
class Node {
protected Node next;
protected Node prev;
protected int value;
public Node() {
}
public Node(int value) {
this.value = value;
}
}
这是我的节点类,我在其中设置了一个条件,该值介于0和11111之间,以便于排序。
public class someName {
protected Node firstSentinel;
protected Node lastSentinel;
public someName() {
firstSentinel = new Node();
lastSentinel = new Node();
firstSentinel.value = 11111;
lastSentinel.value = 0;
firstSentinel.prev = null;
firstSentinel.next = lastSentinel;
lastSentinel.prev = firstSentinel;
lastSentinel.next = null;
}
public void enQueue(Node x) {
if (firstSentinel.next == lastSentinel)// list is empty
{
firstSentinel.next = x;
x.prev = firstSentinel;
x.next = lastSentinel;
lastSentinel.prev = x;
} else {
Node temp = x;
Node curr = firstSentinel.next;
while (curr != lastSentinel && temp.value <= curr.value) {
curr = curr.next;
}
Node tempCurr = curr;
temp.next = tempCurr;
temp.prev = tempCurr.prev;
tempCurr.prev = temp;
tempCurr.prev.next = temp;
}
}
public Node deQueue() {
if (firstSentinel.next == lastSentinel) {
return null;
} else {
Node temp = new Node();
temp = firstSentinel.next;
firstSentinel.next = temp.next;
temp.next.prev = firstSentinel;
return temp;
}
}
public void printt() {
Node temp = new Node();
temp = firstSentinel.next;
while (temp != lastSentinel) {
System.out.println(temp.value);
temp = temp.next;
}
}
public static void main(String[] args) {
someName PQ = new someName();
Node a = new Node(2);
PQ.enQueue(a);
PQ.printt();
Node aa = new Node(456);
PQ.enQueue(aa);
Node aaa = new Node(123);
PQ.enQueue(aaa);
PQ.printt();
Node aaaa = new Node(6);
PQ.enQueue(aaaa);
PQ.printt();
Node aaaaa = new Node(1123);
PQ.enQueue(aaaaa);
PQ.printt();
}
}
当程序运行时,它只输出两个。这使得相信只插入了1个节点(特别是第一个节点)。在这个优先级队列中,我感兴趣的是降序,因此第一个sentinel值被设置为11111,最后一个被设置为0.我认为我在enqueue做了一些愚蠢的事情。如果有人指出我正确的方向,我会很高兴。
答案 0 :(得分:1)
您的enQueue
方法似乎存在缺陷:
public void enQueue(Node x) {
if (firstSentinel.next == lastSentinel)// list is empty
{
firstSentinel.next = x;
x.prev = firstSentinel;
x.next = lastSentinel;
lastSentinel.prev = x;
} else {
Node temp = x;
Node curr = firstSentinel.next;
while (curr != lastSentinel && temp.value <= curr.value) {
curr = curr.next;
}
Node tempCurr = curr;
temp.next = tempCurr;
temp.prev = tempCurr.prev;
tempCurr.prev = temp;
// Think very carefully what this next line does.
// You've just overwritten tempCurr.prev with temp.
// This means you've now assigned temp.next = temp
// That's going to create a cycle.
tempCurr.prev.next = temp;
}
}
如果您只是将该行重新排序到作业之上,那么它可能会按您的意图运作:
public void enQueue(Node x) {
if (firstSentinel.next == lastSentinel)// list is empty
{
firstSentinel.next = x;
x.prev = firstSentinel;
x.next = lastSentinel;
lastSentinel.prev = x;
} else {
Node temp = x;
Node curr = firstSentinel.next;
while (curr != lastSentinel && temp.value <= curr.value) {
curr = curr.next;
}
Node tempCurr = curr;
temp.next = tempCurr;
temp.prev = tempCurr.prev;
tempCurr.prev.next = temp;
// Note here that the assignment to tempCurr.prev happens
// after the assignment to tempCurr.prev.next
tempCurr.prev = temp;
}
}
请注意,您还可以通过完全删除enQueue
来显着简化if
中的逻辑。您当前的else
案例可以处理空案例和非空案例(至少在您修复了我指出的错误之后。)您也不需要temp
变量。< / p>
public void enQueue(Node x) {
Node curr = firstSentinel.next;
while (curr != lastSentinel && x.value <= curr.value) {
curr = curr.next;
}
Node tempCurr = curr;
x.next = tempCurr;
x.prev = tempCurr.prev;
tempCurr.prev.next = x;
tempCurr.prev = x;
}