Firstly I feel I should mention this is for an assignment. I'm not looking for a direct code answer just to point me in the right direction. We have been asked to implement a Priority Queue in a linked list.
I am struggling to write the first part of the insert() function. In the code I try to check if the head contains anything, if not it set's the head to pqItem. It does this, but when insert is called again for a second insert it doesn't recognise that head already has a PQueueItem in it and just overrides head instead of ignoring if (this.head == null). Am I not settting head correctly?
PQueue Class
package ci284.ass1.pqueue;
public class PQueue<T> {
private PQueueItem<T> head;
public static enum ORDER {
ASC, DESC;
}
public static ORDER DEFAULT_ORDER;
private ORDER order;
public PQueue() {
this.order = DEFAULT_ORDER;
head = null;
}
...
public void insert(T data, int priority) {
PQueueItem<T> pqItem = new PQueueItem<T>(data, priority);
PQueueItem<T> temp;
PQueueItem<T> prev;
System.out.println("This is pqItem " + pqItem);
if (this.order == ORDER.DESC || this.order == DEFAULT_ORDER){
if (this.head != null){
System.out.println("Not null " + head);
if (priority <= head.getPriority()){
}
else if (priority > head.getPriority()){
prev = head;
System.out.println(prev);
head.setNext(head);
prev = pqItem;
System.out.println(prev);
}
}
if (this.head == null){
System.out.println("Null " + head);
this.head = pqItem;
System.out.println("Null " + head);
}
}
}
PQueueItem Class
package ci284.ass1.pqueue;
public class PQueueItem<T> {
private int priority;
private T data;
private PQueueItem<T> next;
public PQueueItem(T data, int priority) {
this.data = data;
this.priority = priority;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public PQueueItem<T> getNext() {
return next;
}
public void setNext(PQueueItem<T> next) {
this.next = next;
}
public String toString() {
return String.format("[%s,%d]", data.toString(), priority);
}
}
JUnit Test for insert
#Test
public void testInsertStart(){
PQueue<String> pq = new PQueue<String>();
pq.insert("1",2);
String head = pq.pop();
assertEquals(head, "1");
System.out.println("Worked");
pq.insert("Hiya",3);
assertEquals(head, "Hiya");
}
The test returns:
org.junit.ComparisonFailure: expected:<1> but was:<Hiya>
and the console reads:
This is pqItem [1,2]
Null null
Null [1,2]
Worked
This is pqItem [Hiya,3]
Null null
Null [Hiya,3]
Here is some pseudocode code. (I have tested it by creating a queue)
public void insert(int priority, int data) {
Item item = new Item(priority, data);
if (head == null) {
head = item;
item.setNext(null);
} else {
Item next = head;
Item prev = next;
do {
if (priority > next.getPriority()) {
// break and insert
break;
}
prev = next;
next = next.getNext();
} while (next != null);
item.setNext(next);
if (item.getPriority() > head.getPriority()) {
head = item;
} else prev.setNext(item);
}
}
You had the following problems in your insert method:
prev = head;
head.setNext(head);
prev = pqItem;
What does this piece of code even do? Here is what it does:
You also did not consider the case in which you have more than two items in the queue. Imagine you have 5 items in the queue. And now you want to insert pqItem in the queue. pqItem has the least priority so it will get inserted at the end of the queue, right? Therefore, you need to traverse the queue (list) in order to get to the last item.
Related
I am working on a class assignment and I don't quite understand how to use comparator in the way the assignment is asking.
The assignment reads:
"Complete the Priority Queue class
Your Priority Queue must use an anonymous function to decide priority
It must take the Function interface as a parameter to the constructor
You should still have the default constructor – and if no function is provide use the compareTo function of the class"
This is the class that I am working on...
public class PriorityQueue <Item extends Comparable<Item>> {
public PriorityQueue()
{
}
public PriorityQueue(Comparator<Item> compare )
{
}
private int size = 0;
private Node<Item> head = null;
private Comparator<Item> compare ;
private static class Node<Item>
{
private Item data;
private Node<Item> next;
public Node(Item data, Node<Item> next)
{
this.data = data;
this.next = next;
}
public Node(Item data)
{
this.data = data;
this.next = null;
}
public Node()
{
this.data = null;
this.next = null;
}
}
#Override
public int size() {
return size;
}
#Override
public Item dequeue() {
// TODO Auto-generated method stub
return null;
}
#Override
public void enqueue(Item item) {
Node<Item> curr = head;
Node<Item> prev = curr;
if (isEmpty())
{
head = new Node<Item>(item,null);
}
else
{
while (curr != null)
{
prev = curr;
curr = curr.next;
}
prev.next = new Node<Item>(item, curr);
}
size++;
}
#Override
public boolean isEmpty() {
return size == 0;
}
#Override
public void printQueue() {
Node<Item> curr = head;
while (curr != null)
{
System.out.println(curr.data);
curr = curr.next;
}
}
}
This is the process class that the queue will contain...
public class Process implements Comparable<Process> {
private ProcessPriorty priority;
private String name;
public Process(ProcessPriorty priority, String name) {
super();
this.priority = priority;
this.name = name;
}
public void setPriority(ProcessPriorty priority) {
this.priority = priority;
}
#Override
public String toString() {
return name + "... Priority = " + priority + ".";
}
public String getName() {
return name;
}
public ProcessPriorty getPriority() {
return priority;
}
#Override
public int compareTo(Process other) {
if(other == null)
{
return 1;
}
return this.priority.compareTo(other.priority) ;
}
}
I understand the concept of a queue and have even coded the enqueue method to work as a simple queue that inserts the items as they come in. The problem I am coming across is comparing the nodes within that method to sort the list by priority at insertion. Which I believe relates back to those three directions of the assignment. So, what am I suppose to do with the constructors, the Comparator variable, and how do I make it default to compareTo?
Well since you have a reference to the head of the queue, its pretty simple from there. You have 2 cases -
compare != null
compare == null
In the first case, you are interested in Comparator::compareTo. From the definition of a priority queue, all you have to do is traverse the queue beginning from head, and as soon as the item in enqueue(Item item) is greater than the current element in the traversal, you insert item before element. You'll use compare.compareTo(item, element) to determine their order.
In the second case you'll simply use item.compareTo(element) to make the above stated comparison, the traversal and insertion will be the same.
I am currently learning Doubly Linked Lists.
I have managed to convert write a doubly linked list that was nearly 100% functional. However I need to learn how to write it with tail recursion.
Below is my DLLNode code:
public class DLLNode
{
private DLLNode previous;
public DLLNode next;
private String value;
public DLLNode(String value)
{
this.value = value;
this.previous = previous;
this.next = next;
}
public DLLNode(String value, DLLNode next, DLLNode previous)
{
this.value = value;
this.next = next;
this.previous = previous;
}
public String GetDataItem()
{
return value;
}
public void setDataItem()
{
this.value = value;
}
public DLLNode GetPreviousNode()
{
return previous;
}
public void setPrevious(DLLNode previous)
{
this.previous = previous;
}
public DLLNode GetNextNode()
{
return next;
}
public void setNextNode(DLLNode next)
{
this.next = next;
}
public void addItem(String value) {
if(this.next == null) {
// Stopping condition
DLLNode newNode = new DLLNode(value);
this.next = newNode;
} else {
// Recurse
this.next.addItem(value);
}
}
}
I have managed to get my AddItem working using tail recursion and I'm now looking into getting delete Item working. I'm guessing that like addItem I need deleteItem adding to my DLLNode.
Below is my DoublyLinkedList class:
public class DoublyLinkedList
{
private int noOfItems;
private DLLNode head;
private DLLNode tail;
// Default constructor
public DoublyLinkedList()
{
head = null;
tail = null;
this.noOfItems = 0;
}
public void DeleteItem(int index)
{
if (index ==0)
{
System.out.println("Out of Bounds");
}
if (index > noOfItems)
{
System.out.println("Out of Bounds");
}
if (head == null)
{
System.out.println("No Item to remove");
}
else if (index == 1)
{
head = head.GetNextNode();
noOfItems--;
}
else
{
int position = 0;
DLLNode currentNode = head;
while (currentNode != null) {
if (position == index-1) {
currentNode.setNextNode(
currentNode.GetNextNode().GetNextNode());
noOfItems--;
break;
}
currentNode = currentNode.GetNextNode();
position++;
}
}
}
}
Any tips on where I can get started with converting this code would be greatly appreciated.
Kind Regards,
Ben.
P.S. Apologies for the way the code has formatted - I've tried to fix it but it won't seem to sort. Can anyone good at formatting code on her please try and sort it out?
private void DeleteItemHelper(final int indexToDelete, int curIndex, DLLNode curNode) {
if (curIndex == indexToDelete) {
// Handle removing a node with both a previous and next nodes.
}
else {
DeleteItemHelper(indexToDelete, curIndex + 1, curNode.getNextNode());
}
}
public void DeleteItem(int index) {
DeleteItemHelper(index, 0, head);
}
Without further testing I think that you are forgetting to re-set the head reference of the node following the removed node:
if (position == index-1) {
// Tail of currentNode is set to the node following
// next node, but head of that node still points to the
// node which should be removed from list
currentNode.setNextNode(
currentNode.GetNextNode().GetNextNode());
noOfItems--;
break;
}
Hey ya'll I am having a little trouble with my singly linked list. I decided to create a simple one because we do not get enough practice during my data structures class and cannot seem to find why I am not getting the right output.
The code is:
package linked_list;
public class LinkedList {
private Node head;
private Node tail; // After figuring out head, come back to this FIXME
private int listSize;
public LinkedList() {
head = new Node(null);
tail = new Node(null);
}
public void addLast(String s) {
Node newNode = new Node(s);
if (head == null) {
addFirst(s);
} else {
while (head.next != null) {
head = head.next;
}
head.next = newNode;
tail = newNode;
}
listSize++;
}
public void addFirst(String s) {
Node newNode = new Node(s);
if (head == null) {
head = newNode;
tail = newNode;
}
else {
newNode.next = head;
head = newNode;
}
listSize++;
}
public Object getFirst() {
return head.data;
}
public Object getLast() {
return tail.data;
}
public void clear() {
head = null;
tail = null;
listSize = 0;
}
public Object peek() {
try {
if (head == null) {
throw new Exception ("The value is null");
}
else {
return head;
}
} catch (Exception e) {
System.out.println(e.getMessage());
return null;
}
}
public int size() {
return listSize;
}
// This class has the ability to create the nodes that are used
// in the Linked List.
private class Node {
Node next;
Object data;
public Node(String value) {
next = null;
data = value;
}
public Node(Object value, Node nextValue) {
next = nextValue;
data = value;
}
public Object getData() {
return data;
}
public void setData(Object dataValue) {
data = dataValue;
}
public Node getNext() {
return next;
}
public void setNext(Node nextValue) {
next = nextValue;
}
}
}
Now here is my driver that I created to run a simple little operation:
package linked_list;
public class LinkedListDriver {
public static void main(String[] args) {
LinkedList list1 = new LinkedList();
list1.clear();
list1.addLast("This goes last");
list1.addFirst("This goes first");
list1.addLast("Now this one goes last");
System.out.println(list1.getFirst());
System.out.println(list1.getLast());
}
}
My output is this:
This goes last
Now this one goes last
I guess my question is why am I not getting the answer This goes first from my getFirst() method. It seems to be something wrong with the order or structure of that method but I cannot pinpoint it.
When you are in the else in the addLast, you are changing the reference to head. You should use another reference pointer to traverse the list when adding in the else.
Also, your list size should only be incremented in the else in addLast because you are incrementing twice otherwise (once in addFirst and again after the if-else in addLast).
I am trying to Implement a Linked List Using Java.
The code I have used is as follow
public class LinkNode
{
private int data;
public LinkNode next;
public LinkNode (int data)
{
this.data = data;
}
public void setData(int data)
{
this.data = data;
}
public int getData()
{
return this.data;
}
public void setNext(LinkNode next)
{
this.next = next;
}
public LinkNode getNext()
{
return this.next;
}
public static void main (String [] args)
{
LinkNode Node1 = new LinkNode(3);
LinkNode Head = Node1;
LinkNode Node2 = new LinkNode(4);
LinkNode Node3 = new LinkNode(5);
LinkNode Node4 = new LinkNode(6);
Head.setNext(Node1);
Node1.setNext(Node2);
Node2.setNext(Node3);
Node3.setNext(Node4);
int iCounter =0;
LinkNode currentNode= Head;
while (currentNode.getNext()!=null)
{
int data = currentNode.getData();
System.out.println(data);
currentNode = currentNode.getNext();
iCounter=iCounter+1;
}
System.out.println("No Of Nodes are"+iCounter);
}
}
The Problem here I am getting No of Nodes 3
The code is not counting the last Node that is Node4.
The out put is as follow
3
4
5
No Of Nodes are3
Please let me know what is the problem in the code.
To make Head point to Node1 write
Head = Node1;
If you write Head=null it means that Head doesn't point to any node, and you get a null pointer exception because you then try to get the next node from a node that doesn't exist.
The second problem is that you exit the loop when currentNode.getNext() returns null. The getNext() method returns null when you have reached the last node of the list; if you exit the loop then you won't count the last node. Change the loop condition into:
while (currentNode != null)
And please don't edit the question to ask followup questions. Nobody is notified when a question is edited, so you won't get new answers. It also makes the site less useful for future visitors. Post a new "question" for each question that you have.
Head, should not be null. Instead the data in head should be null, otherwise you have no way to find next.
Here is implementation of Singly Linked List I've developed years ago:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* #author sergiizagriichuk
*/
public class Node<T> {
private T value;
private Node<T> next;
public Node(T value) {
this.value = value;
}
public static <T> Node<T> createLinkedListFromArray(T... array) {
if (checkIfArrayIsNullOrEmpty(array)) return new Node<T>(null);
Node<T> head = new Node<T>(array[0]);
createLinkedList(array, head);
return head;
}
private static <T> boolean checkIfArrayIsNullOrEmpty(T[] array) {
return array == null || array.length == 0;
}
private static <T> void createLinkedList(T[] array, Node<T> head) {
Node<T> node = head;
for (int index = 1; index < array.length; index++) {
T t = array[index];
node.setNext(new Node<T>(t));
node = node.getNext();
}
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public Node<T> getNext() {
return next;
}
public void setNext(Node<T> next) {
this.next = next;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Node node = (Node) o;
return value != null && value.equals(node.value);
}
#Override
public int hashCode() {
return value.hashCode();
}
#Override
public String toString() {
List ret = createList();
return Arrays.toString(ret.toArray());
}
private List createList() {
Node root = this;
List ret = new ArrayList();
while (root != null) {
ret.add(root.getValue());
root = root.getNext();
}
return ret;
}
}
And some Tests:
/**
* #author sergiizagriichuk
*/
public class NodeTest {
#Test
public void testCreateList() throws Exception {
Node<Integer> node = Node.createLinkedListFromArray(1, 2, 3, 4, 5);
Assert.assertEquals(Integer.valueOf(1), node.getValue());
Assert.assertEquals(Integer.valueOf(2), node.getNext().getValue());
}
#Test
public void testCreateListSize() throws Exception {
Integer[] values = new Integer[]{1, 2, 3, 4, 5};
int size = values.length - 1;
Node<Integer> node = Node.createLinkedListFromArray(values);
int count = 0;
while (node.getNext() != null) {
count++;
node = node.getNext();
}
Assert.assertEquals(size, count);
}
#Test
public void testNullNode() throws Exception {
Node<Integer> nullNode = new Node<Integer>(null);
assertNullNode(nullNode);
}
#Test
public void testNullArray() throws Exception {
Node<Integer> nullArrayNode = Node.createLinkedListFromArray();
assertNullNode(nullArrayNode);
}
#Test
public void testSetValue() throws Exception {
Node<Integer> node = new Node<Integer>(null);
assertNullNode(node);
node.setValue(1);
Assert.assertEquals(Integer.valueOf(1), node.getValue());
}
private void assertNullNode(Node<Integer> nullNode) {
Assert.assertNotNull(nullNode);
Assert.assertNull(nullNode.getValue());
}
}
Try to use or redevelop for your situation
I have been diligently watching YouTube videos in an effort to understand linked lists before my fall classes start and I am uncertain how to proceed with iterating over the following linked list. The 'node' class is from a series of videos (same author), but the 'main' method was written by me. Am I approaching the design of a linked list in an illogical fashion (assuming of course one does not wish to use the predefined LinkedList class since the professor will expect each of us to write our own implementation)?:
class Node
{
private String data;
private Node next;
public Node(String data, Node next)
{
this.data = data;
this.next = next;
}
public String getData()
{
return data;
}
public Node getNext()
{
return next;
}
public void setData(String d)
{
data = d;
}
public void setNext(Node n)
{
next = n;
}
public static String getThird(Node list)
{
return list.getNext().getNext().getData();
}
public static void insertSecond(Node list, String s)
{
Node temp = new Node(s, list.getNext());
list.setNext(temp);
}
public static int size(Node list)
{
int count = 0;
while (list != null)
{
count++;
list = list.getNext();
}
return count;
}
}
public class LL2
{
public static void main(String[] args)
{
Node n4 = new Node("Tom", null);
Node n3 = new Node("Caitlin", n4);
Node n2 = new Node("Bob", n3);
Node n1 = new Node("Janet", n2);
}
}
Thanks for the help,
Caitlin
There are some flaws in your linked list as stated by some of the other comments. But you got a good start there that grasps the idea of a linked list and looks functional. To answer your base question of how to loop over this particular implemention of the linked list you do this
Node currentNode = n1; // start at your first node
while(currentNode != null) {
// do logic, for now lets print the value of the node
System.out.println(currentNode.getData());
// proceed to get the next node in the chain and continue on our loop
currentNode = currentNode.getNext();
}
Maybe this will be useful:
static void iterate(Node head) {
Node current = head;
while (current != null) {
System.out.println(current.getData());
current = current.getNext();
}
}
// or through recursion
static void iterateRecursive(Node head) {
if (head != null) {
System.out.println(head.getData());
iterateRecursive(head.getNext());
}
}
class List {
Item head;
class Item {
String value; Item next;
Item ( String s ) { value = s; next = head; head = this; }
}
void print () {
for( Item cursor = head; cursor != null; cursor = cursor.next )
System.out.println ( cursor.value );
}
List () {
Item one = new Item ( "one" );
Item two = new Item ( "three" );
Item three = new Item ( "Two" );
Item four = new Item ( "four" );
}
}
public class HomeWork {
public static void main( String[] none ) { new List().print(); }
}
Good luck!!
You can have your linked list DS class implement 'Iterable' interface and override hasNext(), next() methods or create an inner class to do it for you. Take a look at below implementation:
public class SinglyLinkedList<T>{
private Node<T> head;
public SinglyLinkedList(){
head = null;
}
public void addFirst(T item){
head = new Node<T>(item, head);
}
public void addLast(T item){
if(head == null){
addFirst(item);
}
else{
Node<T> temp = head;
while(temp.next != null){
temp = temp.next;
}
temp.next = new Node<T>(item, null);
}
}
private static class Node<T>{
private T data;
private Node<T> next;
public Node(T data, Node<T> next){
this.data = data;
this.next = next;
}
}
private class LinkedListIterator implements Iterator<T>{
private Node<T> nextNode;
public LinkedListIterator(){
nextNode = head;
}
#Override
public boolean hasNext() {
return (nextNode.next != null);
}
#Override
public T next() {
if(!hasNext()) throw new NoSuchElementException();
T result = nextNode.data;
nextNode = nextNode.next;
return result;
}
}
}