A simple priority queue in Java over a linked list, sorted by priority keys

Now I have this very simple priority queue. add and changePriority they both run into it $ mathcal {O} (n) $ and extractMinimum in the $ Theta (1) $:

net.coderodde.util.pq.PriorityQueue:

package net.coderodde.util.pq;

/**
 * This interface defines the API for priority queue data structures.
 * 
 * @author Rodion "rodde" Efremov
 * @version 1.6 (Oct 3, 2019)
 * @param 
 * @param 

* @since 1.6 (Oct 3, 2019) */ public interface PriorityQueue> { /** * Attempts to add an element to this queue only if it is not yet present. * * @return {@code true} if no duplicates are present and, thus, the element * is added to this priority queue. {@code false} is returned otherwise. */ public boolean add(E element, P priority); /** * Changes the priority of the element. * * @param element the target element. * @param priority the new priority for the element. * @return {@code true} if the priority of the target element changed. * {@code false} otherwise. */ public boolean changePriority(E element, P priority); /** * Removes and returns the element with the highest element. * * @return the highest priority element. * @throws {@link java.lang.IllegalStateException} if the queue is empty. */ public E extractMinimum(); /** * Checks wether the parameter element is in this queue. * * @return {@code true} if the input parameter is in this queue, * {@code false} otherwise. */ public boolean containsElement(E element); /** * The number of elements currently in the queue. */ public int size(); /** * Checks whether this queue is empty. * * @return {@code true} only if this queue contains no elements. */ public boolean isEmpty(); /** * Clears this queue removing all the elements from the queue. */ public void clear(); }

net.coderodde.util.pq.impl.SimplePriorityQueue:

package net.coderodde.util.pq.impl;

import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import net.coderodde.util.pq.PriorityQueue;

/**
 * This class implements a simple priority queue.The elements are ordered in a
 * linked list, the head node of which contains the highest priority element,
 * and the tail node contains the lowest priority element.
 * 
 * @author Rodion "rodde" Efremov
 * @version 1.6 (Oct 3, 2019)
 * @param  the element type.
 * @param 

the priority key type. * @since 1.6 (Oct 3, 2019) */ public final class SimplePriorityQueue> implements PriorityQueue, Iterable { @Override public Iterator iterator() { return new SimplePriorityQueueIterator(); } /** * This static inner class holds an element along with its priority. * * @param the element type. * @param

the priority key type. */ private static final class Node { E element; P priority; Node next; Node prev; Node(E element, P priority) { this.element = element; this.priority = priority; } E getElement() { return element; } P getPriority() { return priority; } void setPriority(P priority) { this.priority = priority; } Node getNextNode() { return next; } Node getPreviousNode() { return prev; } void setNextNode(Node next) { this.next = next; } void setPreviousNode(Node prev) { this.prev = prev; } } /** * Maps each element to the linked list node holding it. */ private final Map> map = new HashMap<>(); private Node headNode = null; private Node tailNode = null; private int size = 0; private int modCount = 0; /** * {@inheritDoc} */ @Override public boolean containsElement(E element) { return map.containsKey(element); } /** * {@inheritDoc} */ @Override public boolean add(E element, P priority) { if (map.containsKey(element)) { // Do not add the duplicates: return false; } Node newNode = new Node<>(element, priority); if (headNode == null) { headNode = newNode; tailNode = newNode; size = 1; modCount++; map.put(element, newNode); return true; } insertNode(newNode); map.put(element, newNode); size++; modCount++; return true; } /** * {@inheritDoc} */ @Override public boolean changePriority(E element, P priority) { if (!map.containsKey(element)) { return false; } Node node = map.get(element); node.setPriority(priority); unlinkNode(node); insertNode(node); return true; } /** * {@inheritDoc} */ @Override public E extractMinimum() { if (size == 0) { throw new NoSuchElementException("Extracting from an empty queue."); } Node topPriorityNode = headNode; headNode = headNode.getNextNode(); if (headNode == null) { tailNode = null; size = 0; } else { headNode.setPreviousNode(null); size--; } map.remove(topPriorityNode.getElement()); modCount++; return topPriorityNode.getElement(); } /** * {@inheritDoc} */ @Override public int size() { return size; } /** * {@inheritDoc} */ @Override public boolean isEmpty() { return size == 0; } /** * {@inheritDoc} */ @Override public void clear() { size = 0; modCount++; map.clear(); } /** * Inserts the given node to its correct location. */ private void insertNode(Node node) { Node currentNode = headNode; // Comparator operator <= instead of < guarantees stability: while (currentNode != null && currentNode.priority.compareTo(node.getPriority()) <= 0) { currentNode = currentNode.getNextNode(); } if (currentNode == null) { tailNode.setNextNode(node); node.setPreviousNode(tailNode); tailNode = node; } else if (currentNode.getPreviousNode() == null) { // The priority of the new element is smaller than the minimum // priority throughout the queue: headNode.setPreviousNode(node); node.setNextNode(headNode); headNode = node; } else { node.setNextNode(currentNode); node.setPreviousNode(currentNode.getPreviousNode()); currentNode.setPreviousNode(node); node.getPreviousNode().setNextNode(node); } } /** * Unlinks the parameter node from the linked list. */ private void unlinkNode(Node node) { if (node.getPreviousNode() != null) { node.getPreviousNode().setNextNode(node.getNextNode()); } else { headNode = node.getNextNode(); } if (node.getNextNode() != null) { node.getNextNode().setPreviousNode(node.getPreviousNode()); } else { tailNode = node.getPreviousNode(); } } /** * This inner class implements an iterator over the priority queue. */ private final class SimplePriorityQueueIterator implements Iterator { private Node node = headNode; private final int expectedModCount = SimplePriorityQueue.this.modCount; @Override public boolean hasNext() { checkComodification(); return node != null; } @Override public E next() { checkComodification(); if (!hasNext()) { throw new NoSuchElementException(); } E returnValue = node.getElement(); node = node.getNextNode(); return returnValue; } private void checkComodification() { if (expectedModCount != SimplePriorityQueue.this.modCount) { throw new ConcurrentModificationException( "Expected modification count: " + expectedModCount + ", " + "actual modification count: " + SimplePriorityQueue.this.modCount); } } } }

net.coderodde.util.pq.impl.SimplePriorityQueueTest:

package net.coderodde.util.pq.impl;

import java.util.Iterator;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;

public class SimplePriorityQueueTest {

    private SimplePriorityQueue queue;

    @Before
    public void setUp() {
        queue = new SimplePriorityQueue<>();
    }

    @Test
    public void testIterator() {
        queue.add(1, 1);
        queue.add(4, 4);
        queue.add(3, 3);
        queue.add(2, 2);

        Iterator iter = queue.iterator();

        assertTrue(iter.hasNext());
        assertEquals((Integer) 1, iter.next());

        assertTrue(iter.hasNext());
        assertEquals((Integer) 2, iter.next());

        assertTrue(iter.hasNext());
        assertEquals((Integer) 3, iter.next());

        assertTrue(iter.hasNext());
        assertEquals((Integer) 4, iter.next());
        // Arrived to the end of the queue:
        assertFalse(iter.hasNext());
    }

    @Test
    public void testContainsElement() {
        assertFalse(queue.containsElement(100));
        assertFalse(queue.containsElement(90));
        assertFalse(queue.containsElement(80));

        queue.add(100, 100);
        queue.add(80, 80);
        queue.add(90, 90);

        assertTrue(queue.containsElement(100));
        assertTrue(queue.containsElement(90));
        assertTrue(queue.containsElement(80));
        assertFalse(queue.containsElement(70));
        assertFalse(queue.containsElement(60));
    }

    @Test
    public void testAdd() {
        assertFalse(queue.containsElement(3));
        queue.add(3, 3);
        assertTrue(queue.containsElement(3));

        assertFalse(queue.containsElement(2));
        queue.add(2, 2);
        assertTrue(queue.containsElement(2));

        assertFalse(queue.containsElement(4));
        queue.add(4, 4);
        assertTrue(queue.containsElement(4));
    }

    @Test
    public void testChangePriority() {
        for (int i = 0; i < 10; i++) {
            queue.add(i, i);
        }

        queue.changePriority(5, -1);
        assertEquals((Integer) 5, queue.extractMinimum());
        assertEquals((Integer) 0, queue.extractMinimum());

        queue.changePriority(1, 100);

        assertEquals((Integer) 2, queue.extractMinimum());
        assertEquals((Integer) 3, queue.extractMinimum());
        assertEquals((Integer) 4, queue.extractMinimum());
        assertEquals((Integer) 6, queue.extractMinimum());
        assertEquals((Integer) 7, queue.extractMinimum());
        assertEquals((Integer) 8, queue.extractMinimum());
        assertEquals((Integer) 9, queue.extractMinimum());
        assertEquals((Integer) 1, queue.extractMinimum());
    }

    @Test
    public void testExtractMinimum() {
        queue.add(5, 5);
        queue.add(3, 3);
        queue.add(4, 4);
        queue.add(7, 7);
        queue.add(6, 6);

        for (int i = 3; i <= 7; i++) {
            assertEquals((Integer) i, queue.extractMinimum());
        }

        // Is the queue stable?
        queue.add(2, 1);
        queue.add(3, 1);
        queue.add(1, 1);

        assertEquals((Integer) 2, queue.extractMinimum());
        assertEquals((Integer) 3, queue.extractMinimum());
        assertEquals((Integer) 1, queue.extractMinimum());
    }

    @Test
    public void testSize() {
        for (int i = 0; i < 10; i++) {
            assertEquals(i, queue.size());
            queue.add(i, i);
            assertEquals(i + 1, queue.size());
        }
    }

    @Test
    public void testIsEmpty() {
        assertTrue(queue.isEmpty());

        queue.add(2, 2);

        assertFalse(queue.isEmpty());

        queue.add(1, 1);

        assertFalse(queue.isEmpty());
    }

    @Test
    public void testClear() {
        queue.clear(); // No-op.

        assertTrue(queue.isEmpty());

        for (int i = 0; i < 5; i++) {
            queue.add(i, i);
            assertFalse(queue.isEmpty());
        }

        queue.clear();
        assertTrue(queue.isEmpty());
    }    
}

Critical request

I'd like to hear comments on test coverage, encoding style, maintainability, and readability, just to name a few. Thank you in advance.

Which HTTP code has a higher priority: 403 or 415?

Consider the following scenario. I need to access a resource hosted on Server X. I would like to receive this resource in a Y format. Therefore, I send along with my request the Accept: Y Header. Unfortunately, X Y does not support and I can not access the X resource either. I have accepted validly Authorization Header.

How should X answer? With a 415 – tell me that it can not speak to me in a desired format or 403 (with a body that I probably can not read because the body parser I use only supports it Y Format).

How does a camera detect the aperture in Shutter Priority mode?

Recently, I experimented with using the shutter priority ("TV" on my Canon dSLR) for pictures taken with my kayak, because motion is a constant factor in this situation (even when there is no wind blowing, there is always a bit of power going on ). , I started with automatic ISO sensitivity, but quickly realized that I had to increase ISO sensitivity to achieve sufficient depth of field, otherwise the camera would use the lowest available ISO sensitivity. When checking the pictures, I am confused about how the camera has selected the aperture. Again and again I see two pictures in a row, taken in the same light with almost the same composition, with different apertures – sometimes very different. Why is this?

nikon – How do I avoid noise in the aperture priority mode created by Auto ISO?

I took photos of birds on a cloudy day and in a wooded area where the light under a tree was even weak compared to other areas.

I used a 70-300mm kit lens. When trying to photograph with 1: 6,3 even with 1/10 or 1/20, the pictures became too dark. I even increased the ISO to 500, but the photos were still dark. I wanted to avoid using a higher ISO value.

If this did not work, I set the camera to the aperture priority mode. This time the photos were clear, at least on the camera screen, but when I transferred them to a computer, I found that the camera automatically increased the ISO to 25600.

This resulted in too much image noise. Even with Lightroom, I can not improve the picture quality. The photo came out blurry.

I checked the values ‚Äč‚Äčthat the camera used in Aperture Priority mode:

  1. 1/400 sec
  2. F 16
  3. 300 mm
  4. ISO 25600

I use the Nikon D 5600 with a 70-300mm kit lens.

How can I adjust the exposure and maintain the sharpness without increasing the ISO in manual mode?

The attached image is an example of a poor quality image.

Enter image description here

Autofocus – When does the Sony NEX-5R use the release priority?

As I understand it, the focus priority delays recording until the focus is reached, while the trigger priority may make a mis-focused shot.

Wikipedia says publishing priority is usually is used in continuous AF mode and focus priority in single-frame AF mode.

Does the "normal" apply to the NEX-5R? When exactly (except for manual focus) does this camera use the trigger priority? The manual says nothing and Google finds nothing.

And how can I turn it off in situations where I would rather wait a fraction of a second than do a wrongly focused shot?

If you do not know the answer to this particular model, you can give me a generic answer that applies to the NEX family, or a test that will help me find out for myself.

Algorithms – Create a priority search tree to determine the number of points in the range [-inf, qx] X [qy, qy’] from a series of points sorted by y-coordinates

A priority search tree can be created for a set of points P in time O (n log (n)). However, if the points are sorted by the y-coordinates, it takes O (n). I find algorithms for constructing the tree if the points are not sorted.

I found a way to do this as follows:

  1. Construct a BST on the points.
    Since the points are sorted, it will take O (n) time

  2. Min-heap the BST on the x-coordinates
    This will take theta (n) time

The total time complexity will be O (n).

Is this a valid approach to creating a priority search tree in O (n) time?

Parser – Do priority and associativity in an LL grammar change the accepted language?

Parsing certainly has priority and associativity on the AST. But do precedence and associativity change the set of accepted sentences? In other words, can the order of precedence and associativity in the grammar be "ignored" and then the AST set later based on (possibly dynamic) ranking and associativity conditions?

I only deal with LL grammars and their common variants.