插入由具有标记的双向链表实现的优先级队列

时间:2014-10-03 01:05:58

标签: java priority-queue doubly-linked-list

我正在使用带有标记的双向链表编写优先级队列

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做了一些愚蠢的事情。如果有人指出我正确的方向,我会很高兴。

1 个答案:

答案 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;
}