I'm trying to implement priority queue using linked nodes, and I have all of my methods working correctly except for the add method. The purpose of the add method is to add a comparable object into the queue in the correct order. The order of the queue is as follows: the highest priority node is the firstNode. Any help as to what I'm doing wrong with my attempt would be much appreciated.
public void add(T newEntry) {
if(newEntry == null) {
return;
}
if(isEmpty()) {
firstNode = new Node(newEntry);
} else {
Node currentNode = firstNode;
if(newEntry.compareTo(firstNode.data)<0) {
firstNode = new Node(newEntry, firstNode);
length++;
return;
} else {
while(currentNode.getNextNode() != null && newEntry.compareTo(currentNode.next.data) > 0) {
currentNode = currentNode.next;
currentNode.setNextNode(new Node(newEntry, currentNode.getNextNode()));
}
}
}
length++;
return;
}
You have at least two problems, which I've pointed out in code comments:
public void add(T newEntry) {
if(newEntry == null) {
return;
}
if(isEmpty()) {
firstNode = new Node(newEntry);
} else {
Node currentNode = firstNode;
if(newEntry.compareTo(firstNode.data)<0) {
// Here you're assigning a new value to firstNode, but not linking to the old
// firstNode. So you're losing the entire list.
firstNode = new Node(newEntry, firstNode);
length++;
return;
} else {
while(currentNode.getNextNode() != null && newEntry.compareTo(currentNode.next.data) > 0) {
currentNode = currentNode.next;
// Here you're adding multiple new nodes to the list.
currentNode.setNextNode(new Node(newEntry, currentNode.getNextNode()));
}
}
}
length++;
return;
}
You can simplify that pretty easily:
public void add(T newEntry) {
if(newEntry == null) {
return;
}
Node newNode = new Node(newEntry);
if(isEmpty()) {
firstNode = newNode;
} else if (newNode.data < firstNode.data) {
// make newNode point to the firstNode,
// and then re-assign firstNode
newNode.setNextNode(firstNode);
firstNode = newNode;
} else {
Node currentNode = firstNode;
Node nextNode = currentNode.getNextNode;
while (nextNode != null && nextNode.data > newNode.data) {
currentNode = nextNode;
nextNode = currentNode.getNextNode;
}
// insert newNode between currentNode and nextNode
newNode.setNextNode(nextNode);
currentNode.setNextNode = newNode;
}
length++;
return;
}
Related
I'm trying to implement delete() method in the LinkedList, which is a custom implementation of the Linked list data structure.
The following code seems to work properly if you delete the first element or an element in the middle. But if I'm trying to delete the last element in the LinkedList, it throws a NullPointerException.
How can I fix this problem?
My code:
public class LinkedList implements List {
Node first;
Node last;
int size;
public LinkedList() {
this.first = null;
this.last = null;
this.size = 0;
}
public void add(double element) {
Node newNode = new Node(element);
if (first == null) {
first = newNode;
last = newNode;
} else {
last.next = newNode;
last = newNode;
}
size++;
}
// more methods (unrelated to the problem)
public void delete(double element) {
if (first == null) {
return;
}
if (first.value == element) {
first = first.next;
return;
}
Node current = first;
Node previous = null;
while (current != null && current.next.value != element) {
previous = current;
current = current.next;
}
if (current == null) {
return;
} else {
current.next = current.next.next;
}
}
#Override
public String toString() {
if (first == null) {
return "[]";
} else {
StringBuffer sb = new StringBuffer();
sb.append("[");
for (Node current = first; current != last; current = current.next) {
sb.append(current.value);
sb.append(",");
}
sb.append(last.value);
sb.append("]");
return sb.toString();
}
}
}
class LinkedListTest {
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.add(5);
list.add(25);
list.add(-7);
list.add(80);
System.out.println(list);
list.delete(80);
System.out.println(list);
}
}
There are two issues in the implementation of the delete() method:
Condition of in the while-loop is not correct. Instead, checking if current != null you need to ensure that current.next is not null (note that it's safe to access the next property of current because iteration starts with current being assigned to first which is proved to be non-null).
You're not considering the edge-case when the Node to remove is the last one. In such a case, when control breaks out from the while-loop current.next would point to last Node, and that would mean the last field should be reassigned (since we're removing the last node).
Also, local variable previous is redundant.
public void delete(double element) {
if (first == null) {
return;
}
if (first.value == element) {
first = first.next;
return;
}
Node current = first;
while (current.next != null && current.next.value != element) {
current = current.next;
}
if (current.next == last) { // reassign last if the Node to be removed is the current last Node
last = current;
}
if (current.next != null) { // if the Node with given value was found
current.next = current.next.next;
}
}
Why am I getting false while doing search(7)?
I tried recursive solution its working fine..
tried implementing with loop failed
public class BST {
class Node {
int data;
Node left , right;
public Node(int data) {
this.data = data;
this.left = this.right = null;
}
}
Node root;
public BST() {
this.root = null;
}
public void insert(int data) {
// create a new node and start iteration from root node
Node newNode = new Node(data);
Node currentNode = this.root;
while (true) {
if (currentNode == null) {
currentNode = newNode;
break;
}
if (data < currentNode.data) { // if data is less go left
currentNode = currentNode.left;
} else if (data > currentNode.data) { // if data is greater go right
currentNode = currentNode.right;
} else { // do nothing for duplicates
break;
}
}
}
public boolean search(int data) {
Node currentNode = this.root;
while (true) {
if (currentNode == null) {
return false;
}
if (data == currentNode.data) {
return true;
} else if (data < currentNode.data) {
currentNode = currentNode.left;
} else {
currentNode = currentNode.right;
}
}
}
public static void main(String... args) {
BST tree = new BST();
tree.insert(15);
tree.insert(7);
System.out.println(tree.search(7));
}
}
Problem is inside the insert method - you are not inserting the nodes correctly inside the tree.
If the tree is empty, you should assign to this.root, not currentNode. Assigning to currentNode has no affect on this.root.
Currently, your code isn't inserting any node inside the tree; it simply assigns the new node to the local variable of insert method, i.e. currentNode.
If the condition data < currentNode.data is true, then you need to check if the currentNode.left is null or not. If it is, then link the new node with the current node as shown below:
currentNode.left = newNode;
If currentNode.left is not null, then do the following:
currentNode = currentNode.left;
Currently, your code moves the currentNode to null and then assigns the newNode to the currentNode without a reference to its parent node in the tree.
Do step 2 for data > currentNode.data as well.
Change the implementation of the insert method as shown below:
public void insert(int data) {
Node newNode = new Node(data);
if (this.root == null) {
this.root = newNode;
return;
}
Node currentNode = this.root;
while (true) {
if (data < currentNode.data) {
if (currentNode.left == null) {
currentNode.left = newNode;
} else {
currentNode = currentNode.left;
}
} else if (data > currentNode.data) {
if (currentNode.right == null) {
currentNode.right = newNode;
} else {
currentNode = currentNode.right;
}
} else {
break;
}
}
}
As I've just started programming a few months back a lot of new information is coming and I'm having trouble catching up.So here I have created what I thought was a sorted linked list.Turns out it is not sorted
public boolean insert(Person person) {
Node n = new Node(person);
Node p = head;
if(p == null) {
head = n;
size++;
return true;
} else {
Node temp = p;
int comparison;
while(temp.next != null) {
comparison = temp.person.name.compareTo(person.name);
if(comparison == 0){
return false;
}
temp = temp.next;
}
temp.next = n;
size++;
return true;
}
}
The method works,it inserts the persons,but they arent sorted like they should be.What part of the code do I need to change/remove in order to make it sort.
Thanks!
You should insert like this:
static boolean insert(Person person) {
Node newNode = new Node(person);
if (head == null) {
head = newNode;
size++;
return true;
}
Node current = head;
Node prev = null;
int comparison;
while (current != null) {
comparison = person.name.compareTo(current.person.name);
if (comparison == 0) {
return false;
} else if (comparison > 0) { /// greater than
if (current.next == null) { // check if reach tail of the linked list add and break
current.next = newNode;
break;
}
} else { // less then
if (prev == null) { // check if it should be first then put and break
Node oldHead = head;
head = newNode;
head.next = oldHead;
break;
}
prev.next = newNode;
newNode.next = current;
break;
}
prev = current;
current = current.next;
}
size++;
return true;
}
There is a problem in your else part. You are returning false when same value is given. But it is not interpreted properly for a valid case.
You need to have as below.
Check current node value - Check for null pointer exception
Check next node value - Check for null pointer exception
If current input is between currentNode and nextNode then do insert between.
If reaches last node, then insert at the end
I have a remove method , find the element in that list and delete it.That topic is about Doubly linked list.Is my operation true in if and else if statement for the formation of the new list?
public void Remove(int key) {//key = number in the list.
if (head == null) {
System.out.println("Empty List..!");
} else if (key == head.key) {
head.prev.next = head.next;
head.next = null;
noOfNodes--;
} else if (key == tail.key) {
tail.next.prev = tail.prev;
tail.prev = null;
noOfNodes--;
} else {
for (LinkedListNode temp = head; temp.next != null; temp = temp.next) {
if (temp.key == key) {
temp.prev.next = temp.next;
temp.next.prev = temp.prev;
temp.prev = null;
temp.next = null;
noOfNodes--;
}
}
}
}
From your code, it looks like tail is the last node of your linked list.
So, this might be the issue tail.next.prev = tail.prev;. Since tail.next is null as tail is the last element, when you access prev on tail.next it throws NullPointerException.
public void insertElementBefore(E element, E newElement) {
MyNode<E> current = head;
if (head != null) {
while (current != null) {
if (current.data.equals(element)) {
MyNode<E> n = new MyNode<E>(newElement);
n.next = current.next;
current.next = n;
return;
}
current = current.next;
}
}
}
This is what I have for this. I'm having troubles to insert the newElement before intended element. Can't seem to figure out the syntax for it. I've been tinkering with it for a while and the best I could get was for it to insert after the element like it currently does
Any help would be greatly appreciated
In case of a single linked list, you will need two temporary nodes:
MyNode<E> current that will represent the current node in the single linked list.
MyNode<E> prev that will represent a node before the current node in the single linked list.
Then, you have to add the new node between these nodes. If you don't have the prev node, then when setting the current node as the next node of the new node, then all the nodes before current will be lost.
This is how your code would look like:
public void insertElementBefore(E element, E newElement) {
MyNode<E> current = head;
//check here
MyNode<E> prev = null;
if (head != null) {
while (current != null) {
if (current.data.equals(element)) {
MyNode<E> n = new MyNode<E>(newElement);
n.next = current;
//check here
if (prev != null) {
prev.next = n;
}
return;
}
//check here
prev = current;
current = current.next;
}
}
}
The trick is to memorise the previous node.
MyNode<E> current = head;
MyNode<E> previous = null;
while (current != null && !current.data.equals(element)) {
return;
}
previous = current;
current = current.next;
}
MyNode<E> n = new MyNode<>(newElement);
n.next = current;
if (previous == null) {
head = n;
} else {
previous.next = n;
}
void Insert_Before(int num)
{
Node *x=new Node();
x->data=num;
if (head==NULL) {
x->next=head;
head=x;
} else {
int c=1;
cout<<"Element before which insertion has to take place:";
cin>>n;
Node *temp=head;
Node *temp1;
//check whether the element is present or not
while (temp->data!=n) { //if present
temp=temp->next;
c=c+1; //finds the position of the element n
}
x->next=temp;
if (c==1) {
head=x;
} else {
int i=1;
while (i<=c-1) {
temp1=temp1->next;
i=i+1;
}
temp1->next=x;
}
}
} //Insert_Before
Node n=headNode;
Node prev=null;
while(n!=null){
if(n.getData()==node){
Node newNode=new Node(data);
prev.setNext(newNode);
newNode.setNext(n);
break;
}
else{
prev=n;
n=n.getNext();
}
}
if(n.getNext()==null){
Node newNode= new Node(data);
prev.setNext(newNode);
newNode.setNext(null);
}
System.out.println("New LinkedList after insert before is:");
printList();
}
Create a new node called previous-node, and keep track of current element. In my code, if the current element matches the value of the node variable, we add a new node before it.