From 3db27719627746c5256053a6afd57c2c85a0ad5c Mon Sep 17 00:00:00 2001 From: Ian Cowan Date: Thu, 4 Nov 2021 19:38:04 -0400 Subject: [PATCH 1/2] Add deque --- DataStructures/Queues/Deques.java | 267 ++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 DataStructures/Queues/Deques.java diff --git a/DataStructures/Queues/Deques.java b/DataStructures/Queues/Deques.java new file mode 100644 index 000000000000..4f5f462bc414 --- /dev/null +++ b/DataStructures/Queues/Deques.java @@ -0,0 +1,267 @@ +package DataStructures.Queues; + +/** + * A [deque](https://en.wikipedia.org/wiki/Double-ended_queue) is short for a + * double ended queue pronounced "deck" and sometimes referred to as a + * head-tail linked list. A deque is a data structure based on a doubly linked + * list, but only supports adding and removal of nodes from the beginning and + * the end of the list. + * + * @author [Ian Cowan](https://github.com/iccowan) + */ +public class Deques { + /** + * Node for the deque + */ + class DequeNode { + /** + * Value of the node + */ + S val; + + /** + * Next node in the deque from this node + */ + DequeNode next = null; + + /** + * Previous node in the deque from this node + */ + DequeNode prev = null; + + /** + * Constructor + */ + DequeNode(S val) { + this.val = val; + } + } + + /** + * Head of the deque + */ + DequeNode head = null; + + /** + * Tail of the deque + */ + DequeNode tail = null; + + /** + * Size of the deque + */ + int size = 0; + + /** + * Adds the specified value to the head of the deque + * + * @param val Value to add to the deque + */ + public void addFirst(T val) { + // Create a new node with the given value + DequeNode newNode = new DequeNode(val); + + // Add the node + if (head == null) { + // If the deque is empty, add the node as the head and tail + head = newNode; + tail = newNode; + } else { + // If the deque is not empty, insert the node as the new head + newNode.next = head; + head.prev = newNode; + head = newNode; + } + + size++; + } + + /** + * Adds the specified value to the tail of the deque + * + * @param val Value to add to the deque + */ + public void addLast(T val) { + // Create a new node with the given value + DequeNode newNode = new DequeNode(val); + + // Add the node + if (tail == null) { + // If the deque is empty, add the node as the head and tail + head = newNode; + tail = newNode; + } else { + // If the deque is not empty, insert the node as the new tail + newNode.prev = tail; + tail.next = newNode; + tail = newNode; + } + + size++; + } + + /** + * Removes and returns the first (head) value in the deque + * + * @return the value of the head of the deque + */ + public T pollFirst() { + // If the head is null, return null + if (head == null) + return null; + + // First, let's get the value of the old head + T oldHeadVal = head.val; + + // Now, let's remove the head + if (head == tail) { + // If there is only one node, remove it + head = null; + tail = null; + } else { + // If there is more than one node, fix the references + head.next.prev = null; + DequeNode oldHead = head; + head = head.next; + + // Can be considered unnecessary... + // Unlinking the old head to make sure there are no random + // references possibly affecting garbage collection + oldHead.next = null; + } + + size--; + return oldHeadVal; + } + + /** + * Removes and returns the last (tail) value in the deque + * + * @return the value of the tail of the deque + */ + public T pollLast() { + // If the tail is null, return null + if (tail == null) + return null; + + // Let's get the value of the old tail + T oldTailVal = tail.val; + + // Now, remove the tail + if (head == tail) { + // If there is only one node, remove it + head = null; + tail = null; + } else { + // If there is more than one node, fix the references + tail.prev.next = null; + DequeNode oldTail = tail; + tail = tail.prev; + + // Similarly to above, can be considered unnecessary + // See `pollFirst()` for explanation + oldTail.prev = null; + } + + size--; + return oldTailVal; + } + + /** + * Returns the first (head) value of the deque WITHOUT removing + * + * @return the value of the head of the deque + */ + public T peekFirst() { + return head.val; + } + + /** + * Returns the last (tail) value of the deque WITHOUT removing + * + * @return the value of the tail of the deque + */ + public T peekLast() { + return tail.val; + } + + /** + * Returns the size of the deque + * + * @return the size of the deque + */ + public int size() { + return size; + } + + /** + * Returns whether or not the deque is empty + * + * @return whether or not the deque is empty + */ + public boolean isEmpty() { + return head == null; + } + + /** + * Returns a stringified deque in a pretty form: + * + * Head -> 1 <-> 2 <-> 3 <- Tail + * + * @return the stringified deque + */ + @Override + public String toString() { + String dequeString = "Head -> "; + DequeNode currNode = head; + while (currNode != null) { + dequeString += currNode.val; + + if (currNode.next != null) + dequeString += " <-> "; + + currNode = currNode.next; + } + + dequeString += " <- Tail"; + + return dequeString; + } + + public static void main(String[] args) { + Deques myDeque = new Deques(); + for (int i = 0; i < 42; i++) { + if (i / 42.0 < 0.5) { + myDeque.addFirst(i); + } else { + myDeque.addLast(i); + } + } + + System.out.println(myDeque); + System.out.println("Size: " + myDeque.size()); + System.out.println(); + + myDeque.pollFirst(); + myDeque.pollFirst(); + myDeque.pollLast(); + System.out.println(myDeque); + System.out.println("Size: " + myDeque.size()); + System.out.println(); + + int dequeSize = myDeque.size(); + for (int i = 0; i < dequeSize; i++) { + int removing = -1; + if (i / 39.0 < 0.5) { + removing = myDeque.pollFirst(); + } else { + removing = myDeque.pollLast(); + } + + System.out.println("Removing: " + removing); + } + + System.out.println(myDeque); + System.out.println(myDeque.size()); + } +} From 1d29f0b584711452478d35fe5b846af3fd75c154 Mon Sep 17 00:00:00 2001 From: Ian Cowan Date: Thu, 4 Nov 2021 19:44:14 -0400 Subject: [PATCH 2/2] Formatted with Google Java Formatter --- DataStructures/Queues/Deques.java | 464 ++++++++++++++---------------- 1 file changed, 222 insertions(+), 242 deletions(-) diff --git a/DataStructures/Queues/Deques.java b/DataStructures/Queues/Deques.java index 4f5f462bc414..499db9cfa417 100644 --- a/DataStructures/Queues/Deques.java +++ b/DataStructures/Queues/Deques.java @@ -1,267 +1,247 @@ package DataStructures.Queues; /** - * A [deque](https://en.wikipedia.org/wiki/Double-ended_queue) is short for a - * double ended queue pronounced "deck" and sometimes referred to as a - * head-tail linked list. A deque is a data structure based on a doubly linked - * list, but only supports adding and removal of nodes from the beginning and - * the end of the list. + * A [deque](https://en.wikipedia.org/wiki/Double-ended_queue) is short for a double ended queue + * pronounced "deck" and sometimes referred to as a head-tail linked list. A deque is a data + * structure based on a doubly linked list, but only supports adding and removal of nodes from the + * beginning and the end of the list. * * @author [Ian Cowan](https://github.com/iccowan) */ public class Deques { - /** - * Node for the deque - */ - class DequeNode { - /** - * Value of the node - */ - S val; - - /** - * Next node in the deque from this node - */ - DequeNode next = null; - - /** - * Previous node in the deque from this node - */ - DequeNode prev = null; - - /** - * Constructor - */ - DequeNode(S val) { - this.val = val; - } - } + /** Node for the deque */ + class DequeNode { + /** Value of the node */ + S val; - /** - * Head of the deque - */ - DequeNode head = null; - - /** - * Tail of the deque - */ - DequeNode tail = null; - - /** - * Size of the deque - */ - int size = 0; - - /** - * Adds the specified value to the head of the deque - * - * @param val Value to add to the deque - */ - public void addFirst(T val) { - // Create a new node with the given value - DequeNode newNode = new DequeNode(val); - - // Add the node - if (head == null) { - // If the deque is empty, add the node as the head and tail - head = newNode; - tail = newNode; - } else { - // If the deque is not empty, insert the node as the new head - newNode.next = head; - head.prev = newNode; - head = newNode; - } - - size++; - } + /** Next node in the deque from this node */ + DequeNode next = null; - /** - * Adds the specified value to the tail of the deque - * - * @param val Value to add to the deque - */ - public void addLast(T val) { - // Create a new node with the given value - DequeNode newNode = new DequeNode(val); - - // Add the node - if (tail == null) { - // If the deque is empty, add the node as the head and tail - head = newNode; - tail = newNode; - } else { - // If the deque is not empty, insert the node as the new tail - newNode.prev = tail; - tail.next = newNode; - tail = newNode; - } - - size++; - } + /** Previous node in the deque from this node */ + DequeNode prev = null; - /** - * Removes and returns the first (head) value in the deque - * - * @return the value of the head of the deque - */ - public T pollFirst() { - // If the head is null, return null - if (head == null) - return null; - - // First, let's get the value of the old head - T oldHeadVal = head.val; - - // Now, let's remove the head - if (head == tail) { - // If there is only one node, remove it - head = null; - tail = null; - } else { - // If there is more than one node, fix the references - head.next.prev = null; - DequeNode oldHead = head; - head = head.next; - - // Can be considered unnecessary... - // Unlinking the old head to make sure there are no random - // references possibly affecting garbage collection - oldHead.next = null; - } - - size--; - return oldHeadVal; + /** Constructor */ + DequeNode(S val) { + this.val = val; } - - /** - * Removes and returns the last (tail) value in the deque - * - * @return the value of the tail of the deque - */ - public T pollLast() { - // If the tail is null, return null - if (tail == null) - return null; - - // Let's get the value of the old tail - T oldTailVal = tail.val; - - // Now, remove the tail - if (head == tail) { - // If there is only one node, remove it - head = null; - tail = null; - } else { - // If there is more than one node, fix the references - tail.prev.next = null; - DequeNode oldTail = tail; - tail = tail.prev; - - // Similarly to above, can be considered unnecessary - // See `pollFirst()` for explanation - oldTail.prev = null; - } - - size--; - return oldTailVal; + } + + /** Head of the deque */ + DequeNode head = null; + + /** Tail of the deque */ + DequeNode tail = null; + + /** Size of the deque */ + int size = 0; + + /** + * Adds the specified value to the head of the deque + * + * @param val Value to add to the deque + */ + public void addFirst(T val) { + // Create a new node with the given value + DequeNode newNode = new DequeNode(val); + + // Add the node + if (head == null) { + // If the deque is empty, add the node as the head and tail + head = newNode; + tail = newNode; + } else { + // If the deque is not empty, insert the node as the new head + newNode.next = head; + head.prev = newNode; + head = newNode; } - /** - * Returns the first (head) value of the deque WITHOUT removing - * - * @return the value of the head of the deque - */ - public T peekFirst() { - return head.val; + size++; + } + + /** + * Adds the specified value to the tail of the deque + * + * @param val Value to add to the deque + */ + public void addLast(T val) { + // Create a new node with the given value + DequeNode newNode = new DequeNode(val); + + // Add the node + if (tail == null) { + // If the deque is empty, add the node as the head and tail + head = newNode; + tail = newNode; + } else { + // If the deque is not empty, insert the node as the new tail + newNode.prev = tail; + tail.next = newNode; + tail = newNode; } - /** - * Returns the last (tail) value of the deque WITHOUT removing - * - * @return the value of the tail of the deque - */ - public T peekLast() { - return tail.val; + size++; + } + + /** + * Removes and returns the first (head) value in the deque + * + * @return the value of the head of the deque + */ + public T pollFirst() { + // If the head is null, return null + if (head == null) return null; + + // First, let's get the value of the old head + T oldHeadVal = head.val; + + // Now, let's remove the head + if (head == tail) { + // If there is only one node, remove it + head = null; + tail = null; + } else { + // If there is more than one node, fix the references + head.next.prev = null; + DequeNode oldHead = head; + head = head.next; + + // Can be considered unnecessary... + // Unlinking the old head to make sure there are no random + // references possibly affecting garbage collection + oldHead.next = null; } - /** - * Returns the size of the deque - * - * @return the size of the deque - */ - public int size() { - return size; + size--; + return oldHeadVal; + } + + /** + * Removes and returns the last (tail) value in the deque + * + * @return the value of the tail of the deque + */ + public T pollLast() { + // If the tail is null, return null + if (tail == null) return null; + + // Let's get the value of the old tail + T oldTailVal = tail.val; + + // Now, remove the tail + if (head == tail) { + // If there is only one node, remove it + head = null; + tail = null; + } else { + // If there is more than one node, fix the references + tail.prev.next = null; + DequeNode oldTail = tail; + tail = tail.prev; + + // Similarly to above, can be considered unnecessary + // See `pollFirst()` for explanation + oldTail.prev = null; } - /** - * Returns whether or not the deque is empty - * - * @return whether or not the deque is empty - */ - public boolean isEmpty() { - return head == null; + size--; + return oldTailVal; + } + + /** + * Returns the first (head) value of the deque WITHOUT removing + * + * @return the value of the head of the deque + */ + public T peekFirst() { + return head.val; + } + + /** + * Returns the last (tail) value of the deque WITHOUT removing + * + * @return the value of the tail of the deque + */ + public T peekLast() { + return tail.val; + } + + /** + * Returns the size of the deque + * + * @return the size of the deque + */ + public int size() { + return size; + } + + /** + * Returns whether or not the deque is empty + * + * @return whether or not the deque is empty + */ + public boolean isEmpty() { + return head == null; + } + + /** + * Returns a stringified deque in a pretty form: + * + *

Head -> 1 <-> 2 <-> 3 <- Tail + * + * @return the stringified deque + */ + @Override + public String toString() { + String dequeString = "Head -> "; + DequeNode currNode = head; + while (currNode != null) { + dequeString += currNode.val; + + if (currNode.next != null) dequeString += " <-> "; + + currNode = currNode.next; } - /** - * Returns a stringified deque in a pretty form: - * - * Head -> 1 <-> 2 <-> 3 <- Tail - * - * @return the stringified deque - */ - @Override - public String toString() { - String dequeString = "Head -> "; - DequeNode currNode = head; - while (currNode != null) { - dequeString += currNode.val; - - if (currNode.next != null) - dequeString += " <-> "; - - currNode = currNode.next; - } - - dequeString += " <- Tail"; - - return dequeString; + dequeString += " <- Tail"; + + return dequeString; + } + + public static void main(String[] args) { + Deques myDeque = new Deques(); + for (int i = 0; i < 42; i++) { + if (i / 42.0 < 0.5) { + myDeque.addFirst(i); + } else { + myDeque.addLast(i); + } } - public static void main(String[] args) { - Deques myDeque = new Deques(); - for (int i = 0; i < 42; i++) { - if (i / 42.0 < 0.5) { - myDeque.addFirst(i); - } else { - myDeque.addLast(i); - } - } - - System.out.println(myDeque); - System.out.println("Size: " + myDeque.size()); - System.out.println(); - - myDeque.pollFirst(); - myDeque.pollFirst(); - myDeque.pollLast(); - System.out.println(myDeque); - System.out.println("Size: " + myDeque.size()); - System.out.println(); - - int dequeSize = myDeque.size(); - for (int i = 0; i < dequeSize; i++) { - int removing = -1; - if (i / 39.0 < 0.5) { - removing = myDeque.pollFirst(); - } else { - removing = myDeque.pollLast(); - } - - System.out.println("Removing: " + removing); - } - - System.out.println(myDeque); - System.out.println(myDeque.size()); + System.out.println(myDeque); + System.out.println("Size: " + myDeque.size()); + System.out.println(); + + myDeque.pollFirst(); + myDeque.pollFirst(); + myDeque.pollLast(); + System.out.println(myDeque); + System.out.println("Size: " + myDeque.size()); + System.out.println(); + + int dequeSize = myDeque.size(); + for (int i = 0; i < dequeSize; i++) { + int removing = -1; + if (i / 39.0 < 0.5) { + removing = myDeque.pollFirst(); + } else { + removing = myDeque.pollLast(); + } + + System.out.println("Removing: " + removing); } + + System.out.println(myDeque); + System.out.println(myDeque.size()); + } }