How to recursively removing an item from linkedList? - java

Implementing LinkedList in a recursive approach was a bit challenging to me, which I get stuck in implementing of its remove method and wonder how to keep reference to previous item in recursive?
MyLinkedList class
package linkedlist;
public class MyLinkedList {
private Integer value;
private MyLinkedList next;
public MyLinkedList() {
}
public MyLinkedList(Integer value) {
this.value = value;
}
public void add(Integer value) {
if (this.value == null) {
this.value = value;
} else if (this.next == null) {
this.next = new MyLinkedList(value);
} else {
this.next.add(value);
}
}
public MyLinkedList remove(Integer index) {
//
// if (index < 0) {
// return this;
// }
// if (index == 0) {
// return this.next;
// }
// this.next = remove(index - 1);
return this;
}
public Integer indexOf(Integer value) {
if (this.value.equals(value)) {
return 0;
} else if (this.next == null) {
return null;
} else {
return 1 + this.next.indexOf(value);
}
}
}
MyLinkedListTester class
package linkedlist;
public class MyLinkedListTester {
public static void main(String[] args) {
MyLinkedList myLinkedList = new MyLinkedList();
myLinkedList.add(1);
myLinkedList.add(2);
myLinkedList.add(3);
myLinkedList.add(4);
System.out.println("Index Of Array: " + myLinkedList.indexOf(3));
MyLinkedList linkedList = myLinkedList.remove(3);
}
}

As mentioned in the comments the iterative approach is easier and more efficient most of the time. Anyway I think you do this as an exercise because in Java you already have a LinkedList.
So first you have a kind of error in your thinking (as far as I'm aware of it). It's also a kind of bad design choice. You create your MyLinkedList and save the data right into it and the next is also of the class MyLinkedList but it's not a list, it's a Node. There should only be one List, and 0 - many nodes.
For example I can't figure out how to do a remove function that will return the removed Node (in your case MyLinkedList) and as well let you keep the list in case you remove the first element in your list.
If you are looking in the implementation that's why they use Nodes and it's also more logical (a list doesn't contain "List elements") and so on...
Some other remark: your indexOf funtion will return an error if you try to get a element that does not exist (1 + null => error).
So anyway. What you have to do is to create a Node. (btw if you really want a real LinkedList you can use generic instead of int/Integer).
Below I post my solution how to do it (may be better out there but that is how I would do it). I also wrote a toString method to see how the List looks like (and it works as far as I can say). In case you want to still use your code without the Node it should give you an idea how to solve your problem with remove. You can also put some of the logic into the Node class but for me Node is only a container and doesn't really contain any logic.
public class MyLinkedList {
private Node head;
public MyLinkedList() {
}
public class Node{
private int value;
private Node next = null;
public Node(int value){
this.value = value;
}
public int getValue(){
return value;
}
public Node getNext(){
return next;
}
public void setNext(Node next){
this.next = next;
}
}
public void add(int value) {
Node next = new Node(value);
if(head == null){
head = next;
} else {
addRecursive(head,next);
}
}
private void addRecursive(Node node, Node next) {
if(node.next == null){
node.setNext(next);
} else {
addRecursive(node.getNext(),next);
}
}
public Node remove(int index){
Node removeNode = head;
if(index == 0){
head = head.getNext();
} else {
removeNode = removeRecursive(head,index-1);
}
return removeNode;
}
private Node removeRecursive(Node node, int index){
Node removeNode = node.getNext();
if(index == 0){
node.setNext(removeNode.getNext());
} else {
removeNode = removeRecursive(node.getNext(),index-1);
}
return removeNode;
}
public int indexOf(int value) {
if (head == null){
return -1;
} else if (head.getValue() == value){
return 0;
} else {
return indexOfRecursive(head,value,0);
}
}
private int indexOfRecursive(Node node, int value, int index) {
if(node.getNext() == null){
return -1;
} else if(node.getNext().getValue() == value){
return index + 1;
} else {
return indexOfRecursive(node.getNext(),value,index+1);
}
}
#Override
public String toString(){
if(head == null){
return "";
} else {
return toStringRecursive(head,"["+head.getValue());
}
}
private String toStringRecursive(Node node, String output){
if(node.getNext() == null){
return output + "]";
} else {
return toStringRecursive(node.getNext(),output + ", " + node.getNext().getValue());
}
}
}

Related

Comparing two valus of Nodes in Binary search trees in java

hey I am new in the binary trees world and I am trying to compare to values to know which direction should I place the newly added node next.
for now, I tried to do CompareTo method but didn't succeed very much I am now trying to make a private method that will give me the value of the Nodes i would love some help
this is my code now I need to add to the if statement the comparing of nodes so I can proceed :
public void add(E data) {
if(root == null) {
return ;
}
if(root.getLeftSon() == null) {
root.setLeftSon((Node<E>) data);
}
else if(root.getRightSon() == null) {
root.setRightSon((Node<E>) data);
}
}
you have to use generics correctly. Parameter has to extend comparable so you can determinate how to sort it.
class BinaryTree<T extends Comparable<T>> {
Node<T> root;
public Node<T> addRecursive(Node<T> current, T value) {
if (current == null) {
return new Node<T>(value);
}
int ord = value.compareTo(current.value);
if (ord > 0) {
current.left = addRecursive(current.left, value);
} else if (ord < 0) {
current.right = addRecursive(current.right, value);
} else {
// value already exists
return current;
}
return current;
}
static class Node<T extends Comparable<T>> {
T value;
Node<T> left;
Node<T> right;
Node(T value) {
this.value = value;
right = null;
left = null;
}
}
}

Make an int search(Object o) method for a stack that uses nodes

I'm trying to make a generic stack and queue class that uses the generic node class. It has empty(), pop(), peek(), push(), and a search() method. I know there is a built-in Stack class and stack search method but we have to make it by using the Node class.
I am unsure of how to make the search method. The search method is supposed to return the distance from the top of the stack of the occurrence that is nearest the top of the stack. The topmost item is considered to be at distance 1; the next item is at distance 2; etc.
My classes are below:
import java.io.*;
import java.util.*;
public class MyStack<E> implements StackInterface<E>
{
private Node<E> head;
private int nodeCount;
public static void main(String args[]) {
}
public E peek() {
return this.head.getData();
}
public E pop() {
E item;
item = head.getData();
head = head.getNext();
nodeCount--;
return item;
}
public boolean empty() {
if (head==null) {
return true;
} else {
return false;
}
}
public void push(E data) {
Node<E> head = new Node<E>(data);
nodeCount++;
}
public int search(Object o) {
// todo
}
}
public class Node<E>
{
E data;
Node<E> next;
// getters and setters
public Node(E data)
{
this.data = data;
this.next = null;
}
public E getData() {
return data;
}
public void setData(E data) {
this.data = data;
}
public Node<E> getNext() {
return next;
}
public void setNext(Node<E> next) {
this.next = next;
}
}
public class MyQueue<E> implements QueueInterface<E>
{
private Node<E> head;
private int nodeCount;
Node<E> rear;
public MyQueue()
{
this.head = this.rear = null;
}
public void add(E item){
Node<E> temp = new Node<E>(item);
if (this.rear == null) {
this.head = this.rear = temp;
return;
}
this.rear.next = temp;
this.rear = temp;
}
public E peek(){
return this.head.getData();
}
public E remove(){
E element = head.getData();
Node<E> temp = this.head;
this.head = this.head.getNext();
nodeCount--;
return element;
}
}
After working on it based off of the first comment I have this:
public int search(Object o){
int count=0;
Node<E> current = new Node<E> (head.getData());
while(current.getData() != o){
current.getNext();
count++;
}
return count;
}
It doesn't have any errors but I cannot tell if it is actually working correctly. Does this seem correct?
It needs the following improvements,
search method should have parameter of type 'E'. So, the signature should look like public int search(E element)
start the count with 1 instead of 0.As you have mentioned topmost item is considered to be at distance 1
initialize current with head, because creating a new node with data value of head(new node(head.getData())) will create an independent node with data same as head node; and the while will run only for the head node as current.getNext() will be null always. Node<E> current = head will create another reference variable pointing to the head.
Instead of != in condition, use if( !current.getData().equals(element.getData())) )
If using your own class as data type, don't forget to override equals method.
Change current.getNext(); to current = current.getNext();
You have problems with other method. Pay attention on top == null. To calculate search() all you need is just iterate over the elements and find position of required value:
public class MyStack<E> {
private Node<E> top;
private int size;
public void push(E val) {
Node<E> node = new Node<>(val);
node.next = top;
top = node;
size++;
}
public E element() {
return top == null ? null : top.val;
}
public E pop() {
if (top == null)
return null;
E val = top.val;
top = top.next;
size--;
return val;
}
public boolean empty() {
return size == 0;
}
public int search(E val) {
int res = 1;
Node<E> node = top;
while (node != null && node.val != val) {
node = node.next;
res++;
}
return node == null ? -1 : res;
}
private static final class Node<E> {
private final E val;
private Node<E> next;
public Node(E val) {
this.val = val;
}
}
}
I assume your MyStack class should be compatible with the Stack class provided by Java as you mention it in your question. This means that your signature public int search(Object o) matches the signature of java.util.Stack#search (apart from synchronised).
To implement the search method using your Node class, we need to traverse the stack and return the index of the first (uppermost) match. First, assign head to a local variable (current). Then you can create a loop where you current.getNext() at the end to get the next element. Stop if the next element is null as we have reached the end of the stack. In the loop, you either count up the index or return this index when the current element's data matches the argument o.
The evaluation needs to be able to deal with null values for your argument o. Therefore, you need to check for null first and adjust your logic accordingly. When o is null, do a null-check against current.getData(). If o is not null, check if current.getData() is equal to o with equals().
Here is a working example: (compatible with java.util.Stack#search)
public int search(Object o) {
int index = 1;
Node<E> current = head;
while (current != null) {
if (o == null) {
if (current.getData() == null) {
return index;
}
} else {
if (o.equals(current.getData())) {
return index;
}
}
current = current.getNext();
index++;
}
return -1; // nothing found
}
To test this, you can write a simple unit test with JUnit like this:
#Test
public void testMyStackSearch() {
// initialize
final MyStack<String> stack = new MyStack<>();
stack.push("e5");
stack.push("e4");
stack.push(null);
stack.push("e2");
stack.push("e1");
// test (explicitly creating a new String instance)
assertEquals(5, stack.search(new String("e5")));
assertEquals(3, stack.search(null));
assertEquals(2, stack.search(new String("e2")));
assertEquals(1, stack.search(new String("e1")));
assertEquals(-1, stack.search("X"));
}
Since you have already a reference implementation, you can replace MyStack with Stack (java.util.Stack) and see if your asserts are correct. If this runs successfully, change it back to MyStack and see if your implementation is correct.
Note: I do not recommend to actually use the Stack implementation in Java. Here, it just serves as a reference implementation for the java.util.Stack#search method. The Deque interface and its implementations offer a more complete and consistent set of LIFO stack operations, which should be used in preference to Stack.

Java double LinkedList remove node

So the idea is to make a Double Ended Priority Queue so far I have got a tree like structure using 2 Linked Lists, I have and interface I have to stick with with no alterations to it. The problem I have got is I have to make 2 methods called getMost and getLeast which gets the most or least node and then makes that node null. But these 2 methods are proving quite difficult to make. How would you go about doing it?
I have tried using recursion but this is proving difficult as I have to select the tree by going tree.root but passing in tree.root into a recursive method always starts it from tree.root
Also I have tried what i have written in inspectLeast() and inspectMost() but Java passes by value not by reference. Any tips?
P.S Not allowed to use anything from java collections or java util.
public class PAS43DPQ implements DPQ
{
//this is the tree
TreeNode tree = new TreeNode();
//this is for the size of the array
int size = 0;
#Override
public Comparable inspectLeast() {
return tree.inspectLeast(tree.root);
}
#Override
public Comparable inspectMost() {
return tree.inspectMost(tree.root);
}
#Override
public void add(Comparable c)
{
tree.add(c);
size++;
}
#Override
public Comparable getLeast() {
if (tree.root != null){
}
return getLeast();
}
#Override
public Comparable getMost(){
Comparable most = getMost();
return most;
}
#Override
public boolean isEmpty() {
return (size > 0)?true:false;
}
#Override
public int size() {
return this.size;
}
class TreeNode{
private Comparable value;
private TreeNode left, right, root;
//constructors
public TreeNode() {}
public TreeNode(TreeNode t) {
this.value = t.value;
this.left = t.left;
this.right = t.right;
this.root = t.root;
}
public TreeNode(Comparable c) {
this.value = (int) c;
}
public void add(Comparable input){
if(root == null){
root = new TreeNode(input);
return;
} else {
insert(root, input);
}
}
public Comparable inspectLeast(TreeNode n){
if (n == null)
return null;
if (n.left == null){
TreeNode least = n;
return least.value;
}
return inspectLeast(n.left);
}
public Comparable inspectMost(TreeNode n){
if (n == null)
return null;
if (n.right == null){
TreeNode most = n;
return most.value;
}
return inspectMost(n.right);
}
public Comparable getMost(TreeNode n){
if(n.right == null)
return n.value;
return tree.getMost(right);
}
public void insert(TreeNode n, Comparable input){
if(input.compareTo(n.value) >= 0){
if (n.right == null) {
n.right = new TreeNode(input);
return;
}
else
insert(n.right, input);
}
if(input.compareTo(n.value) < 0){
if(n.left == null) {
n.left = new TreeNode(input);
return;
}
else
insert(n.left, input);
}
}
}
}
You should be able to modify your TreeNode.getMost(TreeNode n) and TreeNode.getLeast(TreeNode n) similar to the following:
public class TreeNode{
// Also, your parameter here seems to be superfluous.
public TreeNode getMost(TreeNode n) {
if (n.right == null) {
n.root.right = null;
return n;
}
return n.getMost(n);
}
}
Get least should be able to be modified in a similar fashion, but using left rather than right obviously.

Troubles with java generics and linked lists/ques

I am currently running into problems with java generics, linked list/ques structures and methods that should operate on them. Currently, I am trying to write generic methods that should manipulate a linked list of jobs for my school project. I have to implement basic methods, such as enque, de-que, sort-by-priority, get number of elements and so on. The element is, say, a printing job with a priority. A print que shall be implemented as a linked list of jobs. I am not allowed to use any pre-defined collection classes.
This being said, I am not getting something obvious. In the java code shown below, there are 3 classes (Job, MyPrintQue and LinkNode) and one generic interface (PrintQue). I am not importing any other classes from java.util. In the line 85 I use a curr.data.getPriority() method, but curr.data is taken here as the type Object, instead of the type Job, and therefore does have getPriority() method defined. Not sure why is that and how to fix it.
I've gone through a couple of related posts here, but have not found any remedy to my problem. Would be grateful for any input.
Here's the code:
Class Job
public class Job {
private int priority;
public Job(int i) {this.priority=i;}
public int getPriority(){return priority;}
public String toString () {return String.format("This job has priority %d", priority);}
}
Class MyPrintQue
public class ListNode<Job> {
public Job head;
public ListNode<Job> tail;
ListNode (Job j) {this.head=j;}
public Job getHead(){return head;}
public void setHead(Job j){}
}
Interface PrintQue
public interface PrintQue<Job> {
public void enque(Job j);
public void deque(ListNode<Job> n);
public void printQue();
public boolean isEmpty();
public ListNode<Job> hasTheHighestPriority();
public void sortByPriority();
}
and Class MyPrintQue
public class MyPrintQue<Job> implements PrintQue<Job>
{
//Setting up front and end elements of a print que.
private ListNode<Job> front;
private ListNode<Job> end;
private static int queLength;
//Accessors for head and tail.
public ListNode<Job> getFront(){return front;}
public ListNode<Job> getEnd(){return end;}
public void enque(Job j)
{
if (front == null && end == null)
{
front = new ListNode<Job>(j);
queLength++;
}
else if (front !=null & end == null)
{
end = new ListNode<Job>(j);
front.tail =end;
queLength++;
}
else
{
ListNode<Job> temp = new ListNode<Job>(j);
end.tail = temp;
end = temp;
queLength++;
}
}
public boolean find(ListNode<Job> n)
{
for (ListNode<Job> curr = front; curr !=null; curr = curr.tail)
{
if (curr == n) return true;
}
return false;
}
public void deque(ListNode<Job> n)
{
if (find(n))
{
for (ListNode<Job> curr = front; curr !=null; curr = curr.tail)
{
if (front == n) {front = n.tail;}
else if (curr.tail == n) {curr.tail=n.tail;}
}
n = null;
queLength--;
}
}
public void printQue()
{
int length=0;
for (ListNode<Job> curr = front; curr !=null; curr = curr.tail)
{
System.out.println(curr.head);
length++;
}
System.out.println(length);
}
public boolean isEmpty(){if (front == null) return true; else return false;}
public ListNode<Job> hasTheHighestPriority()
{
ListNode<Job> temp = new ListNode<Job>(null);
int prior = 0;
for (ListNode<Job> curr = front; curr.head !=null; curr = curr.tail)
{
if (prior <= ((curr.head).getPriority()))
{
System.out.printf("Current priority is %d, top priority is %d%n", curr.head.getPriority(), prior);
temp = curr;
prior = (int)curr.head.getPriority();
}
}
return temp;
}
public void sortByPriority()
{
MyPrintQue<Job> temp = new MyPrintQue<Job>();
while(!isEmpty())
{
temp.enque(hasTheHighestPriority().head);
deque(hasTheHighestPriority());
}
front = temp.front;
}
}
The difference between your
public class MyPrintQue<Job> implements PrintQue<Job>
and
public class MyJobPrintQue implements PrintQue<Job>
is that in the first case Job is a generic type parameter, nothing to do with the class Job.
And the rewrite, there is a PrintQue of the class Job.
Instead of parameters <Job> better use <J> or whatever.
For good order "queue" is the spelling in English (for an explanation "few" also has double u).
The NullPointerException can be removed by:
if (front == n) {
front = n.tail;
} else {
for (ListNode<Job> curr = front; curr !=null; curr = curr.tail) {
if (curr.tail == n) {
curr.tail = n.tail;
break;
}
}
}

Confused about choosing a loop to iterate a linked list

My problem is in the add method. I think I know what I want it to do but I can't figure out what type of loop I should use to look through the list. As you can see I started to make a if else loop but I couldn't figure out what I should use as the counter. I'm pretty sure I have the right logic in dealing with the add but I feel like I'm not quite there yet. I was thinking of using compareTo in some fashion.
import java.util.*;
public class OrderedLinkedList<E extends Comparable<E>>
{
private Node topNode;
private class Node
{
private E data;
private Node nextNode;
public Node(E data)
{
this.data = data;
nextNode = null;
}
}
public OrderedLinkedList()
{
topNode = null;
}
public boolean empty()
{
if(topNode == null)
return true;
return false;
}
public String toString()
{
String myString = "";
Node nextNode = topNode;
while(nextNode != null)
{
myString = topNode + " -> " + nextNode;
nextNode = topNode.nextNode;
}
return myString;
}
public void add(E data)
{
Node myNode = new Node(data);
Node priorNode = topNode;
Node currentNode = topNode;
if(___)
{
priorNode = currentNode;
currentNode = currentNode.nextNode;
}
else
{
priorNode.nextNode = myNode;
myNode.nextNode = currentNode;
}
}
}
Since you don't typically know the length of a linked list until you've walked down it, the usual thing would be to use a while loop (as you've done in your toString() method)
Perhaps using a doubly linked list would be more beneficial. Consider the following alterations to your class:
import java.util.*;
public class OrderedLinkedList<E extends Comparable<E>>
{
private Node head;
private Node tail;
private class Node
{
private E data;
private Node nextNode;
private Node prevNode;
public Node(E data)
{
this.data = data;
nextNode = null;
prevNode = null;
}
public void setNext(Node node)
{
this.nextNode = node;
}
public Node getNext()
{
return this.nextNode;
}
public void setPrev(Node node)
{
this.prevNode = node;
}
public Node getPrev()
{
return this.prevNode;
}
public E getData()
{
return this.data;
}
public int compareTo(Node that) {
if(this.getData() < that.getData())
{
return -1;
}
else if(this.getData() == that.getData()
{
return 0;
}
else
{
return 1;
}
}
}
public OrderedLinkedList()
{
head = new Node(null);
tail = new Node(null);
head.setNext(tail);
tail.setPrev(head);
}
public boolean empty()
{
if(head.getNext() == tail)
{
return true;
}
return false;
}
public void add(E data) {
Node tmp = new Node(data);
if(this.empty()) {
this.addNodeAfterNode(tmp, head);
} else {
Node that = head.getNext();
// this while loop iterates over the list until finding the correct
// spot to add the new node. The correct spot is considered to be
// when tmp's data is >= that's data, or the next node after 'that'
// is tail. In which case the node is added to the end of the list
while((tmp.compareTo(that) == -1) && (that.getNext() != tail)) {
that = that.getNext();
}
this.addNodeAfterNode(tmp, that);
}
}
private void addNodeAfterNode(Node addNode, Node afterNode)
{
addNode.setNext(afterNode.getNext());
afterNode.getNext().setPrev(addNode);
afterNode.setNext(addNode);
addNode.setPrev(afterNode);
}
}

Categories