Priority queue __java of JAVA queues

Source: Internet
Author: User
Tags array length comparable

Recently, a Full-duplex asynchronous long connection communication component was developed in the project development, and the delay queue was used internally. and the delay queue of the internal implementation of storage is used to the priority queue, when looking at C + + data structure, understand the priority queue, with the storage is two fork tree logic, should be called complete binary tree, can also be called the largest heap.

Next look at the binary tree algorithm, mainly look at the insertion and deletion.

Binary tree as the name suggests is like a tree, under each node can hang up to two nodes, as shown


The way to store in the precedence queue is the queue = {A,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q};

If the current node is labeled I then its child node left = 2*i+1 right = 2*i +2. Priority queue as the name implies, is the priority of the largest queue in the head, and the judgment of priority is based on the object of the Compare method of comparison, to ensure that the root node priority must be greater than the priority of the child nodes. So the elements that are put into the precedence queue either implement the comparable interface or specify a comparer when creating the priority queue.

Let's take a look at the precedence queue constructor

private static final int default_initial_capacity = one;
    Private final comparator<? Super E> Comparator;
    Public Priorityqueue () {This
            (default_initial_capacity, null);
        }
    Public priorityqueue (int initialcapacity,
                             comparator< Super e> Comparator) {
            //note:this restriction of At least one isn't actually needed,
            //But continues for 1.5 compatibility
            if (Initialcapacity < 1)
                throw New IllegalArgumentException ();
            This.queue = new Object[initialcapacity];
            This.comparator = comparator;
        }


When an empty constructor initializes, the array queue size is 11, and the comparer is null. In this case, the object placed in the priority queue implements the comparable interface and can also be judged to be unable to store null elements in the queue.

Now let's take a look at the process of adding an object to the queue.

Public boolean Add (E-e) {return offer
        (e);
    }
Public Boolean offer (E e) {
        if (E = = null)
            throw new NullPointerException ();
        modcount++;
        int i = size;
        if (i >= queue.length)
            Grow (i + 1);
        size = i + 1;
        if (i = = 0)
            queue[0] = e;
        else
            Siftup (i, e);
        return true;
    }

As you can see, there is no possibility of a null element in the precedence queue, adding elements to first modify the number of queues + +, to determine whether to exceed the length of the internal array, after the increase in the length of the array grow (i+1)

private void Grow (int mincapacity) {
        if (mincapacity < 0)//overflow
            throw new OutOfMemoryError ();
	int oldcapacity = queue.length;
        Double size if small; else grow by 50%
        int newcapacity = (Oldcapacity <)?
                           ((oldcapacity + 1) * 2):
                           ((OLDCAPACITY/2) * 3));
        if (newcapacity < 0)//overflow
            newcapacity = integer.max_value;
        if (Newcapacity < mincapacity)
            newcapacity = mincapacity;
        Queue = arrays.copyof (queue, newcapacity);
    }
If the length of the array is less than 64, the length is increased by one time, longer than 64, the original 50 per increment, if the length exceeds the maximum of int, set to
Integer.max_value, if the new length is less than the length required to grow, it is set to this length, and finally the original object is copied to the new array.


This expands the array length and sets the size+1. If it is an empty priority queue, the new element is added to the queue header. If it's not empty, then based on CompareTo to determine the priority of the newly added elements, let's take a look at the Siftup method

private void Siftup (int k, E x) {
        if (comparator!= null)
            Siftupusingcomparator (k, x);
        else
            siftupcomparable (k, x);
    }
private void siftupcomparable (int k, E x) {
        comparable<? super e> key = (comparable<? super e>) x;
        while (k > 0) {
            int parent = (k-1) >>> 1;
            Object e = queue[parent];
            if (Key.compareto ((e) e) >= 0) break
                ;
            Queue[k] = e;
            K = parent;
        }
        QUEUE[K] = key;
    }

    private void Siftupusingcomparator (int k, E x) {while
        (k > 0) {
            int parent = (k-1) >>> 1;
            Object e = queue[parent];
            if (Comparator.compare (x, (e) e) >= 0) break
                ;
            Queue[k] = e;
            K = parent;
        }
        QUEUE[K] = x;
    }

If the comparison tool is specified when the queue is created, then the comparator, the comparator, can be implemented within the comparator, depending on the comparison principle of its definition, or the CompareTo method (if implemented) of the element to which the queue is added, and the comparison method change is defined by itself.

We mainly look at the sorting method without the comparator siftupcomparable, as shown below


Assuming that the smaller the number, the higher the priority, the position of K is the position where the new insertion element will be placed, the insertion is 25, then the priority of this element is less than the priority of its parent node, and the 25 is placed directly in the position of K. If the placement is 8, the highest priority, so (k-1) >>>1 Get the parent node, compared with the parent node, it is found that the priority is greater than the parent node, the value of the parent node is placed in K, the position of K is set to the subscript value of the parent node, the parent node is queried recursively, the position of K is located, and the new element is placed in this position. This kind of two-fork tree algorithm greatly reduces the complexity of the algorithm.


Next, let's take a look at the head element of the queue.

Public E Poll () {if (size = 0) return null;
        int s =--size;
        modcount++;
        E result = (e) queue[0];
        E x = (e) queue[s];
        Queue[s] = null;
        if (S!= 0) siftdown (0, X);
    return result;
        } private void Siftdown (int k, E x) {if (comparator!= null) Siftdownusingcomparator (k, x);
    Else Siftdowncomparable (k, x); } private void Siftdowncomparable (int k, E x) {comparable<? super e> key = (comparable<? Super E&gt
        ;) x;        int half = size >>> 1;  Loop while a non-leaf while (K < half) {int child = (k << 1) + 1;//Assume
            least Object C = queue[child];
            int right = child + 1;
                if (Right < size && (comparable&lt. Super e>) C) compareTo ((E) queue[right]) > 0)
            c = Queue[child = right]; If(Key.compareto ((E) c) <= 0) break;
            QUEUE[K] = c;
        K = child;
    } Queue[k] = key;
        } private void Siftdownusingcomparator (int k, E x) {int half = size >>> 1;
            while (K < half) {int child = (k << 1) + 1;
            Object C = Queue[child];
            int right = child + 1; if (Right < size && Comparator.compare ((e) C, (e) queue[right]) > 0) c = que
            Ue[child = right];
            if (Comparator.compare (x, (E) c) <= 0) break;
            QUEUE[K] = c;
        K = child;
    } Queue[k] = x; }

If the queue has an element, it pops up the element, setting the--size position to null. If not an element, pop the first element, get the last element of the array, and start calling Siftdown (0, X); Let's take a look at the diagram first.


So to poll off the queue head elements, the queue length minus one, so the last element 32 position needs to be set to NULL, so that you need to fill the queue's head, because the child node must be less than equal to the priority of the parent node, get the child node of the parent

int child = (k << 1) + 1; Get subscript for left child node
Object C = Queue[child]; Get left child node
int right = child + 1; Get subscript for right child node

But the right child node does not necessarily exist so the following does a right node is not NULL judgment, NOT NULL case, get two nodes in the higher priority of a

if (Right < size && (comparable<. Super e>) C) compareTo ((E) queue[right]) > 0) {

c = Queue[child = right];

}

The following code means that the following diagram may appear

if (Key.compareto ((E) c) <= 0) {

Break

}



When 21 is moved to the head of the queue, the 32 elements at the end of the queue have priority greater than 68 and 67, and you can place the 32 element directly in the position of 21, ending the loop directly, and reducing the reordering algorithm for the location of the vacated elements below.

With a while (k

Priority queue is also the two more important methods, for the Remove (Object O) method, is to delete the middle node after the first sort, and then the process of sorting up, you can view.


Welcome to the Exchange.

























Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.