Removal at index from doubly linked list java - java

Here is the beginning of the class if it helps at all. I'm trying to write a method to remove an element from a specific index in the doubly linked list. I'm not sure if I'm remotely on the right path but this is what i've done and I'm getting a NullPointerException at:
prevNode.next = nextNode;
public class DoublyLinkedList {
Node start;
Node end;
int length;
public DoublyLinkedList() {
this.start = null;
this.end = null;
this.length = 0;
}
public void removeAtIndex(int index) {
Node currentNode = start;
for (int i = 0; i < index; i++) {
if (index < 0 || index > length) {
System.out.println("The index is out of bounds");
return;
} else if (currentNode == null) {
System.out.println("The list is empty");
return;
} else if (i == index - 1) {
Node nextNode = currentNode.next;
Node prevNode = currentNode.prev;
prevNode.next = nextNode;
nextNode.prev = prevNode;
return;
}
currentNode = currentNode.next;
}
}

With your flow, it is return null because the currentNode is null at first.
Let's take a look at your code. (I guess you've started programing, right :P)
Move out the check IndexOutOfBounds from the for, nothing to do with for loop here.
Your idea about remove item at i by set pre node linked to next node, It is OK, and i see your code is fine.
I hope that you have implemented the addNode to increase the length, because it will not go into the for loop.
Once again, check out your code and clear your mind. Many return is not really good.

Related

Insert a node at a specific position in a linked list JAVA

public static SinglyLinkedListNode insertNodeAtPosition(SinglyLinkedListNode llist, int data, int position) {
if(llist == null) {
llist = new SinglyLinkedListNode(data);
return llist;
} else {
for (int i = 0; i < position-1; i++) {
llist = llist.next;
}
SinglyLinkedListNode temp = llist;
llist.next = new SinglyLinkedListNode(data);
llist = llist.next;
llist.next = temp.next;
return llist;
}
}
This is my code to place a custom index node in LinkedList. But hackerrank is not accepting my code. What's wrong with my algorithm?
The problem is that your code always returns the newly created node, but you should always return the first node in the list, which either is what it was when you got it, or is the new node in case the position was zero.
What to look at:
I'll not provide the corrected code, but will give you two hints:
By moving llist ahead in the for loop, you lose the reference to that first node, so use a different variable for walking through the list.
Also, you should deal specifically with the case where position is 0, as this is the only case where the returned value is not the original llist value, but the new node's reference, much like you have in the if block.
Easiest solution No need of explaination :
Solution :
static SinglyLinkedListNode insertNodeAtPosition(SinglyLinkedListNode head, int data, int position) {
if (head == null) return null;
SinglyLinkedListNode temp = new SinglyLinkedListNode(data);
if (position == 0) {
temp.next = head;
return temp;
}
SinglyLinkedListNode p = head;
for (int i = 0; i< position-1; i++) {
p = p.next;
}
SinglyLinkedListNode next = p.next;
p.next = temp;
temp.next = next;
return head;
}
The problem requires you to return a linked list. When we are asked to return a linked list, actually we return the first node of the linked list.
So, your problem is the returned value in your code script is not the first node of the linked list.
The simplest solution is that you keep the first node in another variable, and
return that variable after you have done the insert thing.
for example:
SinglyLinkedListNode dumyNode = llist;
......
return dumyNode;
Suppose given the correct Node class, you can try this approach (without index collision case):
private Node find(int index) {
Node curr = head;
for (int i = 0; i < index; i++)
curr = curr.next;
return curr;
} // end find()
public Object get(int index) throws IndexOutOfBoundsException {
if (index >= 0 && index < size) {
Node curr = find(index);
return curr.data;
} else {
throw new IndexOutOfBoundsException();
} // end if - else
} // end get()
public void add(Object data, int index) throws IndexOutOfBoundsException {
if (index >= 0 && index < size + 1) {
if (index == 0)
head = new Node(data);
else {
Node prev = find(index - 1);
prev.next = new Node(data);
} // end if - else
size++;
} else {
throw new IndexOutOfBoundsException();
} // end if - else
} // end add()

Remove method for a linked list. Insert method is untraditional and runs on theta(1) time

Hello all so I have a linked list here and I have to make a remove method that works properly. For example if I call remove(0) it should delete the first thing that was entered in the list and so on and so forth. This is a little bit different than most linked lists because usually the head node is at the 0ith place however in this case the head is at the end of the list. So my code so far works pretty good however I am unable to delete the head node or the last item in my list. Also if my list only has one element in it, it is also unable to be deleted. My code works for all other cases I have looked at examples for deleting the head node however it doesn't seem to work in my case. If anyone can help me out it would be greatly appreciated!
public class MyLinkedList {
private MyNode head;
private int numberElements;
public MyLinkedList() {
numberElements = 0;
head = null;
}
// runtime = \Theta(1)
// if you don't care about ordering
// every time something is inserted it becomes the head node
public void insert(MyCircle m) {
MyNode temp = new MyNode();
temp.setData(m);
temp.setNext(head);
head = temp;
numberElements++;
}
// runtime = \Theta(n)
public void remove(int index) {
if (index >= numberElements || index < 0) {
throw new RuntimeException("Index too big or too small!");
}
MyNode current = head;
if (index == numberElements) {
head = head.getNext(); // I have seen this in other examples to delete the head node. However It does not work for mine.
}
int length = numberElements - index - 2;
for (int i = 0; i < length; i++) {
current = current.getNext();
}
if (index != 0 && index != numberElements) {
current.setNext(current.getNext().getNext());
} else if (index == 0) {
current.setNext(null);
}
numberElements--;
}
// runtime = \Theta(n)
public void print() {
// loop through the list until getNext is null
MyNode current = head;
while (current != null) {
System.out.println(current.getData());
current = current.getNext();
}
}
}
I figured it out. A simple - 1 had to be added.
MyNode current = head;
if (index == numberElements ** - 1 **) {
head = head.getNext(); // I have seen this in other examples to delete the head node. However It does not work for mine.
}

I wrote a delete method for a node in Linked List at specific index (Java) but it makes no changes to the list?

The code makes no changes to the output and just reprints the original linked list and I don't know whether the problem is with my delete method or with the access specifiers I used for my Stack.
List item
Public static class Stack
{
Node first; *// newest node added*
private int size;
class Node
{
String item;
Node next;
}
public Node delete(int index,Stack list)
{
if (list.first== null) {
return null;
} else if (index == 0)
{
return list.first.next;
}
else
{
Node n = list.first;
for (int i = 0; i < index - 1; i++)
{
n = n.next;
if(i==index)
n.next = n.next.next;//skips over the existing element
}
return list.first;
}
}
}
//client test code
public static void main(String[] args) {
StdOut.print("Type the linked list:");
Stack list = new Stack();
int index;
String in=StdIn.readLine();
for(int i=0;i<=in.length();i++)
{
list.push(in);
}
StdOut.print("Type the index to be deleted:");
index=StdIn.readInt();
StdOut.println("Before deleting element at "+ index);
StdOut.println(in);
StdOut.println("After deleting element at "+ index);
StdOut.print(list.delete(index,list).item);
}
}
In your delete() function, you are returning list.first - which is pointing to the head node of the list, and not the Node first* //newest node added*, correct? I think you should just be returning from the function when the delete task is complete instead of returning null or a node.
Also, as you iterate through the list in the final else statement, you should move the n = n.next; line below the index check.
Your delete() function would look something like this:
public Node delete(int index,Stack list)
{
if (list.first== null)
{
return;
} else if (index == 0)
{
return;
}
else
{
Node n = list.first;
for (int i = 0; i < index; i++)
{
//If the next Node of the current node is +1 the current index
if(i+1==index)
{
n.next = n.next.next;//skips over the existing element
return;
}
n = n.next;
}
return;
}
}
And :
list.delete(index,list).item; //call the delete function
StdOut.println("After deleting element at "+ index);
list.print(); //Print the list using its print function (assuming you have one)
I hope this helps!

Linked list code for deleting an item at a particular position

I am working on Singly linked lists and have coded a function that will delete an element at a particular position in the linked list.
Problems I am facing is I am unable to delete an element if there is only one element left in the linked list.
Here is my code:
void deleteAtPosN(int position) {
int i = 1;
LinkedList temp = head;
if (position <= 0)
return;
while (i < position - 1) {
temp = temp.next;
++i;
}
if (temp == null) {
System.out.println("list is empty");
} else if (i == position) {
temp = null;
} else {
LinkedList deleteElement = temp.next;
temp.next = deleteElement.next;
}
}
Why your code does not work
When you get to the last item you set temp to null, but that does not affect the linked list in memory, it just changes your local copy to be equal to null.
How to fix
You want to keep a reference to the previous element, and modify it's next, instead of keeping the current item
Pseudocode
fun removeN(index) {
var current = head
var last = null
for (int i = 0; i < index; i++) {
last = current
current = current.next
i++
}
if (last == null) {
// We are at the head of the list
head = current.next
} else {
last.next = current.next
}
}
You have an iterative solution by #jrtapsell that keeps track of the last and the current pointers. Here is a recursive solution that keeps track of all the last pointers via the recursive call stack. The recursive solution is easier to understand and write, but the iterative solution is better IMO because it has O(1) extra memory overhead as opposed to O(N).
//zero based indexing, assumes position >= 0
public void deleteAtPosN(int position)
{
head = deleteAtPosNHelper(head, position);
}
//assumes position >= 0
private LinkedList deleteAtPosNHelper(LinkedList current, int position)
{
if (current == null)
{
return null;
}
else if (position == 0)
{
return current->next;
}
else
{
current->next = deleteAtPosHelper(current->next, --position);
return current;
}
}

trim() method for linked list

I have a question, I've looked around on the internet but couldn't find an example. But making a String trim() method in java (remove lead/trailing whitespace), I know the basic code for this is:
public LString trim(){
int i = this.size;
int j = 0;
int k = this.offset;
char[] arrayOfChar = this.data;
while ((j < i) && (arrayOfChar[(k + j)] <= ' '))
++j;
while ((j < i) && (arrayOfChar[(k + i - 1)] <= ' '))
--i;
return (((j > 0) || (i < this.size)) ? substring(j, i) : this);
}
But, how would you write this same method, but applied to a linked list? More specifically, a linked list that uses a Node class.
Here is what I did....correct me if this is wrong...I'll include relevant class information that pertains to the question.
public class LString{
private Node front = null; //first val in list
private Node back; //last val in list
private int size = 0;
private int i;
private int offset;
public LString(){
//construct empty list
Node LString = new Node();
front = null;
}
.......//skip down some methods to this one
//returns new lstring that is slice of lstring
//contains an endIndex as well
public LString substring(int beginIndex, int endIndex){
Node current = this.front;
int size = 0;
while(current != null && size < beginIndex){
size++;
current = current.getNext();
}
front = new Node();
front.setData(current.getData());
Node ocurrent = front;
while(current != null && size < endIndex){
current = current.getNext();
Node curr2 = new Node();
curr2.setData(current.getData());
ocurrent.setNext(curr2);
ocurrent = curr2;
size++;
}
ocurrent.setNext(null); //set next val to null to term string
return this;
}
public LString trim(){
String lstr;
int i = this.size;
int m = this.offset;
int k = charAt(m);
Node current = front;
while(current != null){
current = current.getNext();
if(current.data > '\u0020'){
return this;
} else if(current.data < '\u0020'){
LString lstring = new LString(); //this worked!?
return lstring;
}
}
return this.substring(k, m+1);
}
...............................................................
//My Node class:
public class Node{
public char data;
public Node next;
//constructors from page 956
public Node()
{
this('\0',null); //'\0' is null char for java
}
public Node(char initialData, Node initialNext)
{
data = initialData;
next = initialNext;
}
}
(If you are unfamiliar with the node class, it basically just creates a singly linked node to use as your links between data in your linked list class)
I've never seen an example or anything, so I thought I'd ask the community.
Assuming that
by trimming the list you want to remove leading and trailing elements that are null
and under "linked list that uses a Node class" you mean java.util.LinkedList
You should keep in mind that in java internal implementation of LinkedList is not exposed (note: java.util.LinkedList.Node has private access modifier), all modifications are performed through methods of iterator and LinkedList itself.
Implementation would be:
public static void trim (LinkedList list){
if (list == null || list.size() == 0) return;
Object element = null;
ListIterator i = list.listIterator();
while (i.hasNext() && element == null) {
element = i.next();
if (element == null) {
i.remove();
}
}
element = null;
i = list.listIterator(list.size());
while (i.hasPrevious() && element == null) {
element = i.previous();
if (element == null) {
i.remove();
}
}
}
However if you are reimplementing mutable strings via linked list as an exercise
(if not as an exercise then stop right there and use StringBuilder or StringBuffer), then, assuming that you implement it with doubly linked list, it will go like this:
EDIT: my bad, you can iterate to the first non-empty element and set reference directly to it, updated algorithm
Fetch first element
While fetched element is empty fetch next
Set head reference to the last fetched element, set last fetched element's prev reference to null
Fetch last element
While fetched element is empty fetch previous
Set tail reference to the last fetched element, set last fetched element's next reference to null
UPDATE With code you provided try something like this (since you are using singly-linked list, it is slightly different then the one described above):
public void trim(){
//early out if empty
if (front == null || back==null) return;
Node current = front;
//looking for the first non-empty element
while(current != null && current.data<'\u0020' ){
current = current.next;
}
//left trim
this.front = current;
//looking for last non-empty element
while (current!=null&&current.next!=null&&current.next.data>'\u0020'){
current = current.next;
}
//right trim
this.back = current;
if (current!=null){
current.next = null;
}
}
Assuming you just want to trim each String in a LinkedList, why not just iterate over each item?
LinkedList<String> myNodes = new LinkedList<String>();
myNodes.add('This is a node ');
myNodes.add(' another node '));
for (String s : myNodes){
s.trim();
}

Categories

Resources