Java double LinkedList remove node - java

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.

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;
}
}
}

How to recursively removing an item from linkedList?

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());
}
}
}

comparator can be constructed directly? got confuse since comparator is a interface.

I saw it creates a Comparator directly in this piece of code and it can be run successfully, I got confused since Comparator is a interface. All the examples I can find are classes implemented Comparator interface.
public class Solution
{
private Comparator<ListNode> ListNodeComparator = new Comparator<ListNode>(){
public int compare(ListNode left, ListNode right) {
if (left == null) {
return 1;
} else if (right == null) {
return -1;
}
return left.val - right.val;
}
};
public ListNode mergeKLists(ArrayList<ListNode> lists)
{
if (lists == null || lists.size() == 0) {
return null;
}
Queue<ListNode> heap = new PriorityQueue<ListNode>(lists.size(), ListNodeComparator);
for (int i = 0; i < lists.size(); i++) {
if (lists.get(i) != null) {
heap.add(lists.get(i));
}
}
ListNode dummy = new ListNode(0);
ListNode tail = dummy;
while (!heap.isEmpty())
{
ListNode head = heap.poll();
tail.next = head;
tail = head;
if (head.next != null) {
heap.add(head.next);
}
}
return dummy.next;
}
}
Actually, what you are doing here, is creating an anonymous class, which implements the interface:
private Comparator<ListNode> ListNodeComparator = new Comparator<ListNode>(){ // here starts the implementation
#Override
public int compare(ListNode left, ListNode right) {
if (left == null) {
return 1;
} else if (right == null) {
return -1;
}
return left.val - right.val;
}
};
Is actually the same as:
public class MyClass implementsComparator<ListNode>(){
#Override
public int compare(ListNode left, ListNode right) {
if (left == null) {
return 1;
} else if (right == null) {
return -1;
}
return left.val - right.val;
}
};
If you only need to use the implementation once, in one class, it's not necessary to create a separate class with implementation.
It's not really creating the comparator directly, that's an anonymous class, where a class is created with no name. This would be equivalent:
class A implements Comparator<ListNode> {
#Override
public int compare(ListNode left, ListNode right) {
if (left == null) {
return 1;
} else if (right == null) {
return -1;
}
return left.val - right.val;
}
}
and then:
Comparator<ListNode> listNodeComparator = new A();

Properly Writing Object Oriented Code in java for a stack

I'm trying to write code in a way that it is object oriented. In this particular case I want to keep track of the minimum value of my stack in O(1) time. I know how to do it, the idea of it, well my idea of it, which is to have another stack that keeps track of the minimum value for every push and pop.
I've nested every class inside of the program class which is called minStack, which doesn't seem like the right thing to do however when I create a instance of minStack and call its variables it works out fine for a regular stack. I created a class that extends a Stack called StackWithMin but I don't know how to call its values. Should I create a new instance of a StackWithMin? If so how would i do it? I did it at the end of the code above the main function, but peek() always returns null
class minStack {
public class Stack {
Node top;
Object min = null;
Object pop() {
if(top != null) {
Object item = top.getData();
top = top.getNext();
return item;
}
return null;
}
void push(Object item) {
if(min == null) {
min = item;
}
if((int)item < (int)min) {
min = item;
}
Node pushed = new Node(item, top);
top = pushed;
}
Object peek() {
if(top == null) {
//System.out.println("Its null or stack is empty");
return null;
}
return top.getData();
}
Object minimumValue() {
if(min == null) {
return null;
}
return (int)min;
}
}
public class Node {
Object data;
Node next;
public Node(Object data) {
this.data = data;
this.next = null;
}
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
public void setNext(Node n) {
next = n;
}
public Node getNext() {
return next;
}
public void setData(Object d) {
data = d;
}
public Object getData() {
return data;
}
}
public class StackWithMin extends Stack {
Stack s2;
public StackWithMin() {
s2 = new Stack();
}
public void push(Object value) {
if((int)value <= (int)min()) {
s2.push(value);
}
super.push(value);
}
public Object pop() {
Object value = super.pop();
if((int)value == (int)min()) {
s2.pop();
}
return value;
}
public Object min() {
if(s2.top == null) {
return null;
}
else {
return s2.peek();
}
}
}
Stack testStack = new Stack();
StackWithMin stackMin = new StackWithMin();
public static void main(String[] args) {
minStack mStack = new minStack();
//StackWithMin stackMin = new StackWithMin();
mStack.testStack.push(3);
mStack.testStack.push(5);
mStack.testStack.push(2);
mStack.stackMin.push(2);
mStack.stackMin.push(4);
mStack.stackMin.push(1);
System.out.println(mStack.testStack.peek());
System.out.println(mStack.stackMin.peek());
mStack.testStack.pop();
}
}
I would suggest to create generic interface Stack like this one
interface Stack<T> {
void push(T item);
T pop();
T peek();
}
Generics add stability to your code by making more of your bugs
detectable at compile time.
See more about generics here.
Then implement this interface in a common way. All implementation details will be hidden inside of this class (your Node class for example). Here is the code (it is just to show the idea, if you want to use it you need to improve it with exception handling for example). Note that class Node is now also generic.
class SimpleStack<T> implements Stack<T> {
private class Node<T> { ... }
private Node<T> root = null;
public void push(T item) {
if (root == null) {
root = new Node<T>(item);
} else {
Node<T> node = new Node<T>(item, root);
root = node;
}
}
public T pop() {
if (root != null) {
T data = root.getData();
root = root.getNext();
return data;
} else {
return null;
}
}
public T peek() {
if (root != null) {
return root.getData();
} else {
return null;
}
}
}
Now we get to the part with stored minimum value. We can extend our SimpleStack class and add field with another SimpleStack. However I think this is better to make another implementation of the Stack and store two stacks for values and for minimums. The example is below. I have generalize the class that now uses Comparator to compare object, so you can use any other object types.
class StackWithComparator<T> implements Stack<T> {
private Comparator<T> comparator;
private SimpleStack<T> mins = new SimpleStack<>();
private SimpleStack<T> data = new SimpleStack<>();
public StackWithComparator(Comparator<T> comparator) {
this.comparator = comparator;
}
public void push(T item) {
data.push(item);
if (mins.peek() == null || comparator.compare(mins.peek(), item) >= 0) {
mins.push(item);
} else {
mins.push(mins.peek());
}
}
public T pop() {
mins.pop();
return data.pop();
}
public T peek() {
return data.peek();
}
public T min() {
return mins.peek();
}
}
Now you can use both implementations like so
SimpleStack<Integer> s1 = new SimpleStack<>();
s1.push(1);
s1.push(2);
s1.push(3);
System.out.println(s1.pop()); // print 3
System.out.println(s1.pop()); // print 2
System.out.println(s1.pop()); // print 1
StackWithComparator<Integer> s2 = new StackWithComparator<>(new Comparator<Integer>() {
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
});
s2.push(1);
s2.push(2);
s2.push(3);
s2.push(0);
s2.push(4);
System.out.println(s2.min() + " " + s2.pop()); // print 0 4
System.out.println(s2.min() + " " + s2.pop()); // print 0 0
System.out.println(s2.min() + " " + s2.pop()); // print 1 3
System.out.println(s2.min() + " " + s2.pop()); // print 1 2
System.out.println(s2.min() + " " + s2.pop()); // print 1 1

Implementing splay() method for Binary Search Tree

I am trying to implement a splay(Node x) method for a Binary Search Tree. I have the leftRotation(Node x) and rightRotation(Node x) methods implemented correctly (atleast, I think they are...), but when I try to implement them in a splay(Node x) method, it calls itself in an infinite loop. Now, I know why it's doing that, but can't seem to figure out how to fix it.
Here is the leftRotation(Node x) method:
public void leftRotation(Node<E> x) {
if (x.getRightChild() == null) {
return;
}
Node<E> y = x.getRightChild();
x.setRightChild(y.getLeftChild());
if (y.getLeftChild() != null) {
y.getLeftChild().setParent(x);
}
y.setParent(x.getParent());
if (x.getParent() == null) {
root = y;
} else {
if (x == x.getParent().getLeftChild()) {
x.getParent().setLeftChild(y);
} else {
x.getParent().setRightChild(y);
}
}
y.setLeftChild(x);
x.setParent(y);
}
Here's the rightRotation(Node x) method:
public void rightRotation(Node<E> x) {
if (x.getLeftChild() == null) {
return;
}
Node<E> y = x.getLeftChild();
x.setRightChild(y.getRightChild());
if (y.getRightChild() != null) {
y.getRightChild().setParent(x);
}
y.setParent(x.getParent());
if (x.getParent() == null) {
root = y;
} else {
if (x == x.getParent().getRightChild()) {
x.getParent().setRightChild(y);
} else {
x.getParent().setLeftChild(y);
}
}
x.setRightChild(x);
x.setParent(y);
}
And here's the splay(Node x) method:
public void splay(Node<E> x) {
while (x.getParent() != null) {
if (x.isLeftChild && x.getParent().isLeftChild) {
this.rightRotation(x.getParent());
this.rightRotation(x);
} else if (x.isRightChild && x.getParent().isRightChild) {
this.leftRotation(x.getParent());
this.leftRotation(x);
} else if (x.isLeftChild && x.getParent().isRightChild) {
this.rightRotation(x);
this.leftRotation(x);
} else if (x.isRightChild() && x.getParent().isLeftChild()) {
this.leftRotation(x);
this.rightRotation(x);
} else if (x.isLeftChild && x.getParent() == root) {
this.rightRotation(x);
} else if (x.isRightChild && x.getParent() == root) {
this.leftRotation(x);
}
}
}
Any ideas on how to fix the infinite loop? It seems to be something to do with it not breaking out of the while(x.getParent() != null) statement in the splay(Node x) method, but when I went through the code using the debugger, the properties of the node seemed to be changing, so I don't really know where it's going wrong?
setLeftChild(Node leftChild) method:
public void setLeftChild(Node<E> leftChild) {
this.leftChild = leftChild;
if (leftChild != null) {
leftChild.setIsRightChild(true);
leftChild.setParent(this);
}
}
Apart from all the mistakes/bad things I pointed out in your code, here is the biggest one, in rightRotation :
x.setRightChild(x);
This creates a cycle in your tree, hence the infinite loop. You should have unit tested your methods. One other major error in your code is that your if - else if instructions do not have an else so there might be cases where nothing happens during an iteration... hence the infinite loop. It's not the case here because you considered all the cases (actually, you considered even more, and the two last ones will never be executed because the four first cases cover every possible case) but as a general remark, this was really dangerous to code it that way.
Here is the code of my own implementation of all these methods, which I deem cleaner :
public class BinaryTree<T extends Comparable<T>> {
private Node<T> root;
public void rebalance(Node<T> node) {
while (!node.isRoot()) rotation(node.getParent(), node.getChildKind().opposite());
}
private void rotation(Node<T> node, Side side) {
if (node.getChild(side.opposite()) == null) return;
Node<T> sideChild = node.getChild(side.opposite());
node.setChild(sideChild.getChild(side), side.opposite());
if (node.getParent() == null) setRoot(sideChild);
else node.getParent().setChild(sideChild, node.getChildKind());
sideChild.setChild(node, side);
}
private void setRoot(Node<T> root) {
this.root = root;
if (root != null) root.setRoot();
}
private static enum Side {
LEFT, RIGHT;
public Side opposite() { return this == LEFT ? RIGHT : LEFT; }
}
private static class Node<T extends Comparable<T>> {
private T value;
private Node<T> left, right, parent;
public Node(T value) { this(value, null, null, null); }
public Node(T value, Node<T> left, Node<T> right, Node<T> parent) {
setValue (value );
setLeft (left );
setRight (right );
setParent(parent);
}
public Node<T> setLeft(Node<T> left) {
this.left = left;
if (left != null) left.parent = this;
return this;
}
public Node<T> setRight(Node<T> right) {
this.right = right;
if (right != null) right.parent = this;
return this;
}
public Node<T> setChild(Node<T> child, Side side) { return side == Side.LEFT ? setLeft(child) : setRight(child); }
public Node<T> setRoot() { return setParent(null); }
private Node<T> setParent(Node<T> parent) {
this.parent = parent;
return this;
}
public Node<T> setValue(T value) {
this.value = notNull(value);
return this;
}
public boolean isRoot() { return parent == null; }
public boolean isLeftChild () { return isRoot() || getParent().getValue().compareTo(getValue()) > 0; }
public boolean isRightChild() { return isRoot() || !isLeftChild() ; }
public Node<T> getChild(Side side) { return side == Side.LEFT ? getLeft() : getRight(); }
public Side getChildKind() {
Check.isFalse(isRoot(), "This method is not defined on root nodes");
return isLeftChild() ? Side.LEFT : Side.RIGHT;
}
public T getValue () { return value ; }
public Node<T> getLeft () { return left ; }
public Node<T> getRight () { return right ; }
public Node<T> getParent() { return parent; }
}
}
Note : my tree is not always optimally rebalanced. I did this out of my head but I will check at Wikipedia to see what they say, I probably did not apply the right algorithm, but it works pretty fine already expect in pathologic cases.

Categories