Changing Deque elements - java

I have made my own Deque class with the following methods:
Deque#pushLeft(E e), pushRight(E e), popLeft() and popRight().
Is it possible to make a method which could change any elements of a Deque? I would like to edit them from left and from right. So editRight(index, E newElement) and the same for editLeft.
How would I start doing this? Would I need to use an Iterator?

You have implemented your Deque as a double linked list. The simplest way to support editLeft and editRight is to just step along the links until you reach the node you wish to change.
Something like:
public void editLeft(int index, Item item) {
Node node = right;
while (node != null && index > 0) {
node = node.prev;
index--;
}
if (node != null) {
node.item = item;
} else {
throw new IllegalRangeException("Attempt to edit value with illegal index");
}
}

Deque is ADT and it could be implemented by linked list or Arrays as data structures. Your answer depends upon the type of data structure being used to store elements.and also I would suggest you to implement a peek operation and it would give you a reference of an element for edit propose .peek operation could be used by other high-level operations like delete/contains etc.

Related

How can I inverse a list of elements if I can only access to an element and his next one?

I have been given a "class" called LinkedList which has only one atributte
"Node first" which refers to the first element of a list. The way to access the other ones is that class "Node" has access to an element 'x' and his following one:
public class LinkedList<T> {
private static class Node<E> {
E elem;
Node<E> next;
Node (E elem) {
this.elem = elem;
this.next = null;
}
}
private Node<T> first;
So that, I have been ordered to do a method called "reverse" from class "LinkedList" which has to reverse the list. However, the difficulty of the exercise is that I can only re-link the attributte "first", I mean I cannot create auxiliar data structures and that type of help.
I have done this in order to achieve the last element of the list, but I dont know how to continue:
public void reverse () {
Node<T> aux = first.next;
while (aux.next != null) {
first.elem = aux.elem;
aux = aux.next;
}
first.elem = aux.elem;
}
It seems quite a theoretical question to me, so you might want to check Geek for Geeks first. Most of these questions that are used in programming courses are well explained there, including coding examples.
In this case, a well-known solution is to use three pointers: a current number, the previous number , and the next number; to keep track of nodes to update reverse links.
Check here: https://www.geeksforgeeks.org/reverse-a-linked-list/

How to implement an iterator for a custom doubly linked list implementation?

I'm implementing a custom doubly linked list in Java and I don't know exactly how to implement an iterator for it so that it can for example be easily iterated using a foreach (enhanced for) loop.
I basically want to be able to get the next or previous element with something like the code below, where it starts from a given Node and then continues to get the "next" (or "previous") element in the node variable. I want it to stop once "next" is null (which obviously will be handled by "hasNext").
I know that the approach below might not strictly make sense from a Java perspective because what I'm searching for is a for loop that does not loop through a Collection but logically it makes sense.
for (Node node : firstNode)
Otherwise I would need to do something like
Node node = getFirstNode();
while (node != null) {
//do stuff with current node
node = node.next;
}
The reason I don't want to use java.util.LinkedList is because of the lower amount of memory that will be used with the custom approach. Basically I also need the "next" and "previous" references in a Node so that I can easily access them with just having the Node at hand. If I would go with the java.util.LinkedList approach for each Node additionally I would need to keep an integer index to indicate at which index the object is located in the list and then be able to access "next" or "previous" or edit the list at that location in O(1) time.
Note that I would still prefer the java.util.LinkedList approach If there is a way to get away without needing the indexInList variable in the Node itself
Here is a very basic implementation of Iterator for a linked list that only iterates forward using the next pointer:
class NodeIterator implements Iterator<Node> {
Node current;
public NodeIterator(Node firstInList) {
this.current = firstInList;
}
#Override
public boolean hasNext() {
return current != null;
}
#Override
public Node next() {
Node savedCurrent = current;
current = current.next;
return savedCurrent;
}
}
To be able to use the enhanced for loop syntax, your custom linked list has to implement the Iterable interface. That interface has just one method, which creates a new iterator:
class LinkedList implements Iterable<Node> {
Node first;
#Override
public Iterator<Node> iterator() {
return new NodeIterator(first);
}
}
For reference, the Node class:
class Node {
Node next;
// add other fields you need
}

Remove All Occurrences of a Given Value from a Doubly Linked List

Alright, so cut a long story short, what I'm trying to do here is remove all instances of value e from a doubly linked list. As far as I know, my logic is at least mostly right, but for some off reason it isn't actually removing any of the nodes in my test cases.
public boolean removeAll(int e) {
DIntNode dummy = head,next = null;
if (head == null)
return false;
while (dummy != null) {
if (dummy.getData() == e) {
next = dummy.getNext();
dummy.getNext().setPrev(null);
dummy = next;
return true;
}
else
dummy = dummy.getNext();
}
return false;
}
This is what I currently have for my code of the metho. My logic here was to use a dummy DIntNode that starts at the head and a "next" node to help me shrink the list, so to speak. In other words, if the list was something like "1<-> 1 <-> 2 <-> 3", the function would change it to "2<->3", in theory. The reason this is a boolean function is because I'm required to return true if the given value is removed form the list.
Is there just another step in the logic that I'm missing, or is the methodology itself just unreliable? I'm very unsure at this point, so any and all help would be greatly appreciated.
You set
dummy.getNext().setPrev(null);
But previous node also have reference to next node you try to remove. You should set this reference to next active value.
That because when you want to get all linked list previous value still know about node you remove, because of next node reference
You can try with the following code:
if (dummy.getData() == e) {
DIntNode temp = dummy.getPrevious();
temp.next = dummy.getNext();
temp = dummy.getNext();
temp.previous = dummy.getPrevious();
return true;
}
This used the previous reference. So the previous node will now have reference to the next node of your dummy node (node to be deleted). And similarly, the next node of dummy node will have reference of previous node of your dummy node. So, the dummy node will loose its connection/link from its doubly link list and that's what we want!
Please try.
Two issues with the code:
When relinking a doubly linked list, where removing B from A - B - C, you need to set the next node for A to be C as well as the previous node for C to be A. With trying to keep you method names:
A.setNext(current.getNext());
C.setNext(current.getPrev());
With your code, if you find an occurrence, you return, which means that no other instances will be removed since you jump out of that method. You will probably need a new boolean removed variable, that is set to false, return true changed to removed = true and return false changed to return removed.
The method exits after the first encounter of 'e'.
If you want to remove all instances of 'e', then you should have something like this:
boolean listChanged = false;
while (dummy != null) {
if (dummy.getData() == e) {
// update list
...
listChanged = true;
}
...
}
return listChanged;
Also, you should not write your code like this:
dummy.getNext().setPrev(...); // throws NPE if next is null

Setting myself to null - Java

I came across the following problem:
Delete a node in the middle of a singly linked list, given only access to that node. (head is not given)
Now there are a lot of solutions and they all do not work when the element to be deleted is the last node.
Why wouldn't this work?
public static void removeNode (Node n){
if(n.next == null){ //n is the last node
n= null;
return;
}
//handling general case here
}
Java passes parameters by value, so setting n to null has no effect outside of the method. This means the method essentially does nothing when passed the last node of a list.
You need to set null the reference in the previous node, not the variable that references to your last node, something like this:
if(n.next == null) {
prev.next = null;
return;
}
n is local to the method, so changing its value won't affect the list itself. You need to modify the next of the previous node, which you do not have access to.

Adding objects to binary search tree

I'm completely new to BST and how they work if this is completely wrong it would be appreciated if I could get a link to a reference site or something. right now I'm writing a program to add values from an ArrayList of Strings to a BST and I come up with errors such as The method compareTo(Node) is undefined for the type ArrayList<String>. I thought by having extends Comparable it would account for comparing ArrayList values but I'm not using E. Also I had to add a cast to s to set it as the root but I feel like there is an easier way. I don't know if I can add ArrayList values the way I'm doing it, this is just how it looks in the book I'm using for reference. This is my code, any help would be appreciated, I already tried looking up things in the Java API and that didn't help:
public class BinarySearchTree<E extends Comparable<? super E>>
{
public void add(ArrayList<String> s, Node n) {
if (n == null)
n = (Node) s;
else if (s.compareTo(n) < 0)
add(s, n.leftChild);
else
add(s, n.rightChild);
}
}
I think this reference would be helpful to you: Binary Search Trees - Stanford Library
First of all, the Node class should extend Comparable and override the compareTo method in it. ArrayList class doesn't extend Comparable and hence the following will not work
s.compareTo(n) < 0
s being an ArrayList reference. Also, you are trying to compare an ArrayList reference with a Node reference which is totally incorrect. You need to compare two Node values.
It looks like you are trying to add the entire ArrayList as a single node of your BST. My guess is that you are supposed to construct a BST from the elements of the ArrayList. For that, I would suggest defining two functions:
public Node add(ArrayList<String> s, Node root) {
for (String elt : s) {
root = add(elt, root);
}
}
public Node add(String elt, Node root) {
if (root == null) {
root = // new Node with data set to elt
} else if (elt.compareTo(n.data()) < 0) {
root.left = add(elt, root.left);
} else if (elt.compareTo(n.data()) > 0) {
root.right = add(elt, root.right);
} else {
// duplicate element being inserted -- error?
}
return root;
}

Categories