【问题标题】:Insertion into a priority queue implemented by doubly linked list with sentinels插入到由带哨兵的双向链表实现的优先级队列中
【发布时间】:2014-10-03 01:05:58
【问题描述】:

我正在使用带哨兵的双向链表编写优先级队列

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();
    }
}

当程序运行时,它只输出二进制。这让人相信只有一个节点(尤其是第一个节点)被插入。在这个优先级队列中,我对降序感兴趣,因此第一个哨兵值被设置为 11111,最后一个被设置为 0。我认为我在队列中做了一些愚蠢的事情。如果有人指出我正确的方向,我会很高兴。

【问题讨论】:

  • 尝试使用调试器 (jdb) 单步执行代码。

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


【解决方案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;
    }
}

请注意,您还可以通过完全删除 if 来显着简化 enQueue 中的逻辑。您当前的 else 案例可以处理空案例和非空案例(至少在您修复了我指出的错误之后)。您也不需要 temp 变量。

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

【讨论】:

    猜你喜欢
    • 2017-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-22
    • 2017-02-08
    相关资源
    最近更新 更多