简体   繁体   中英

How To Implement Correct Sorting Algorithm in Priority Queue?

I need your help with implementing the correct sorting algorithm for Priority Queue. Apparently I've done this wrong as it creates a duplicate node. I'm stumped on this, any help would be greatly appreciated. I need to get this right as I will use this on both increase() and decrease() methods.

Check my sort() method below in the code.

Here is my code:

public class PriorityQueueIntegers implements PriorityQueueInterface {

    // number of elements
    private int numberOfElements;

    // element
    private int element;

    // priority
    private int priority;

    // Node
    Node head = null, tail = null;

    // returns true if the queue is empty (no items in queue)
    // false if queue is (has at least one or more items in queue)
    public boolean isEmpty()
    {
        return ( numberOfElements == 0 );
    }

    // returns the value of the item currently at front of queue
    public int peek_frontValue()
    {
        return head.getValue();  // return the value in the head node
    }

    // returns the priority of the item currently at front of queue
    public int peek_frontPriority()
    {
        return head.getPriority();
    }

    // clear the queue
    public void clear()
    {
        head = null;
        tail = null;
        numberOfElements = 0;
    }

    // insert the item with element and priority
    public void insert(int newElement, int newPriority)
    {
        // if head node is null, make head and tail node contain the first node
        if (head == null)
        {
            head = new Node(newElement, newPriority);
            tail=head; // when first item is enqueued, head and tail are the same
        }
        else
        {
            Node newNode = new Node(newElement, newPriority);
            tail.setNext(newNode);
            tail=newNode;            
        }
        sort(newElement, newPriority);

        numberOfElements++;
    }

    public void increase(int findElement, int priority_delta)
    {
        Node current = head;

        if (numberOfElements > 0)
        {
            while (current != null)
            {
                if (current.getValue() == findElement)
                {
                    int newPriority = current.getPriority() + priority_delta;
                    current.setIncreasePriority(newPriority);
                }
                current = current.getNext();
            }
        } else throw new UnsupportedOperationException("Empty Queue - increase failed");
    }

    public void decrease(int findElement, int priority_delta)
    {
        Node current = head;

        if (numberOfElements > 0)
        {
            while (current != null)
            {
                if (current.getValue() == findElement)
                {
                    int newPriority = current.getPriority() - priority_delta;
                    if (newPriority < 0)
                    {
                        throw new UnsupportedOperationException("Can't be a negative number");
                    }
                    current.setDecreasePriority(newPriority);
                }
                current = current.getNext();
            }
        } else throw new UnsupportedOperationException("Empty Queue - increase failed");
    }

    private void sort(int value, int priority)
    {
        Node current = head;
        int v = value;
        int p = priority;

        Node temp = new Node(v, p);

        if (numberOfElements > 0)
        {
            while (current != null && current.getNext().getPriority() < p)
            {
                current = current.getNext();
            }
            temp._next = current._next;
            current._next = temp;
        }
    }

    public int remove_maximum()
    {
        int headDataValue = 0;
        if ( numberOfElements > 0 )
        {
            headDataValue = head.getValue();
            Node oldHead=head;
            head=head.getNext();
            oldHead.setNext(null);                     
            this.numberOfElements--;
        }
        else throw new UnsupportedOperationException("Empty Queue - dequeue failed");
        return headDataValue;  // returns the data value from the popped head, null if queue empty
    }

    public String display()
    {
        Node current = head;
        String result = "";

        if ( current == null )
        {
            result = "[Empty Queue]";
        }
        else
        {
            while ( current != null )
            {
                result = result + "[" + current.getValue() + "," + current.getPriority() + "] ";
                current = current.getNext();
            }
        }

        return result;
    }

    //////////////////////////////////////////////////////////////

    // Inner Node Class
    private class Node
    {
        private int value;
        private int priority;
        private Node _next;

        public Node (int element, int priority_delta)
        {
            this.value = element;
            this.priority = priority_delta;
            _next = null;
        }

        protected Node(int element, int priority_delta, Node nextNode)
        {
            this.value = element;
            this.priority = priority_delta;
            _next = nextNode;
        }

        public Node getNext()
        {
            return _next;
        }

        public int getValue()
        {
            return this.value;
        }

        public int getPriority()
        {
            return this.priority;
        }

        public void setIncreasePriority(int newPriority)
        {
            this.priority = newPriority;
        }

        public void setDecreasePriority(int newPriority)
        {
            this.priority = newPriority;
        }

        public void setNext(Node newNextNode)
        {
            _next = newNextNode;
        }

    }
}

You are correct that your code currently creates duplicate nodes. Your insert method creates a node:

    if (head == null) {
        head = new Node(newElement, newPriority);
        tail=head; // when first item is enqueued, head and tail are the same
    } else {
        Node newNode = new Node(newElement, newPriority);
        tail.setNext(newNode);
        tail=newNode;            
    }

This method then calls sort that also creates a node:

    Node temp = new Node(v, p);
    if (numberOfElements > 0) {
        while (current != null && current.getNext().getPriority() < p) {
            current = current.getNext();
        }
        temp._next = current._next;
        current._next = temp;
    }

It does not make a lot of sense to me that a sort method would create a new node. You should either insert the node in the right position in insert or the sort method should move it to the correct position. If you take the first approach then you'll need to change you increase and decrease methods.

A potential method to move a node to the correct position, in pseduocode, would be:

move node:
    walk through queue and find both
        node that's next points to the one you are moving (from)
        last node that has higher priority than the one you are moving (to)
    set from.next to node.next
    set node.next to to.next
    set to.next to node

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM