I have an implementation of doubly linked list , and I'm trying to delete a particular node at a given position. I managed to delete the second node to the last node but when I try to delete the first node it fails, I wonder what's wrong with my code.
I've already tried this but still doesn't work
head.next.previous = null;
head = head.next;
This is my code
public class Proses {
private class Node{
String Matkul;
int NilaiUts;
int NilaiUAS;
Node previous;
Node next;
public Node(String Matkul, int Nilai, int NilaiUAS) {
this.Matkul = Matkul;
this.NilaiUts = Nilai;
this.NilaiUAS = NilaiUAS;
}
}
Node head, tail = null;
public void addNode(String matkul, int Nilai, int NilaiUAS) {
Node newNode = new Node(matkul, Nilai, NilaiUAS);
if(head == null) {
head = tail = newNode;
head.previous = null;
tail.next = null;
} else {
tail.next = newNode;
newNode.previous = tail;
tail = newNode;
tail.next = null;
}
}
public void delete(int position){
if (head == null || n <= 0)
return;
Node current = head;
int i;
for (i = 1; current != null && i < position; i++)
{
current = current.next;
}
if (current == null)
return;
deleteNode(head, current);
}
//delete function
public Node deleteNode(Node head, Node del){
if (head == null || del == null){
return null;
}
if (head == del){
head = del.next;
del.next.previous = null;
}
if (del.next != null){
del.next.previous = del.previous;
}
if (del.previous != null){
del.previous.next = del.next;
}
del = null;
return head;
}
}
Using your code, if the scenario is such that it ends up with 1 node (head will be pointing to this node) and you want to delete this node (i.e. head), code will fail with NullPointerException at
del.next.previous = null;
as del.next is NULL;
Use can take a look at below code to delete a Node from doubly linked list
// Function to delete a node in a Doubly Linked List.
// head_ref --> pointer to head node pointer.
// del --> data of node to be deleted.
void deleteNode(Node head_ref, Node del)
{
// Base case
if (head == null || del == null) {
return;
}
// If node to be deleted is head node
if (head == del) {
head = del.next;
}
// Change next only if node to be deleted
// is NOT the last node
if (del.next != null) {
del.next.prev = del.prev;
}
// Change prev only if node to be deleted
// is NOT the first node
if (del.prev != null) {
del.prev.next = del.next;
}
// Finally, free the memory occupied by del
return;
}
code ref: https://www.geeksforgeeks.org/delete-a-node-in-a-doubly-linked-list/
The problem with your code is that, head is not getting changed in deleteNode function because it's pass by value. Consider the following scenario:
You are deleting the position 1. Head is pointing to the node1, so
it store the address of node1. assume it's 1001.
Now you call deleteNode function with head reference and currentNode, so head reference is get passed to the function argument as pass by value. so in function argument head contains the address 1001.
Now you perform the delete operation, so the function's head is changing it's position to the next node. But, your class member's head is still pointing to the first position.
To overcome this, you can set the head again, because you are returning it from the deleteNode function. Like:
Change the code as follow
public void delete(int position){
if (head == null || n <= 0)
return;
Node current = head;
int i;
for (i = 1; current != null && i < position; i++)
{
current = current.next;
}
if (current == null)
return;
head = deleteNode(head, current);
}
Related
How can I add it and delete Node First and delete Node Last in a double-link list
Just want to add delete Node First and delete Node Last. I did not know how to add it in your programming, but I want to help it solve it
i have 3 class
class node .
class doublyLinkedListMain .
class doublyLinkedList .
I want to add special programming in class doublyLinkedList this one delete Node First and delete Node Last
class doublyLinkedList
{
Node head;
public void push(int newdata)
{
Node NewNode = new Node(newdata);
NewNode.next = head;
NewNode.prev = null;
if (head != null) head.prev = NewNode;
head = NewNode;
}
public void insertAfter(Node PrevNode, int newdata)
{
if (PrevNode == null)
{
System.out.println("The given previous node cannot be null");
return;
}
Node NewNode = new Node(newdata);
NewNode.next = PrevNode.next;
PrevNode.next = NewNode;
NewNode.prev = PrevNode;
if (NewNode.next != null)
NewNode.next.prev = NewNode;
}
public void append(int newdata)
{
Node NewNode = new Node(newdata);
Node last = head;
NewNode.next = null;
if (head == null)
{
NewNode.prev = null;
head = NewNode;
return;
}
while (last.next != null) last = last.next;
last.next = NewNode;
NewNode.prev = last;
return;
}
void insertBefore(Node NextNode, int newdata)
{
if (NextNode == null)
{
System.out.println("the given next node cannot be NULL");
return;
}
Node NewNode = new Node(newdata);
NewNode.data = newdata;
NewNode.prev = NextNode.prev;
NextNode.prev = NewNode;
NewNode.next = NextNode;
if (NewNode.prev != null)
NewNode.prev.next = NewNode;
else head = NewNode;
}
void deleteNode( Node del)
{
if (head == null || del == null) return;
if (head == del) head = head.next;
if (del.next != null) del.next.prev = del.prev;
if (del.prev != null) del.prev.next = del.next;
return;
}
void printList()
{
Node n = head;
while (n != null)
{
System.out.print(n.data+" ");
n = n.next;
}
System.out.print(" \n ") ;
}
}
sorry, but you have different mistakes in your code. Firstly, for a list you need two or three pointers as attribute in your List class (Node head /* begin */, tail /* end */, current /* yes, the current element on which you have access */ - I have learned it with a current pointer but depending on your implementation you can do it without it too). Because of that, you must change some of your code. For example, you need a hasAccess() : boolean method, if you use a current pointer, which return current != null and your methods must consider and use tail. Furthermore, you should add a method isEmpty():
public boolean isEmpty() {
return head == null;
}
This method checks if the list is empty. In the case, that the list is empty (the method returns true), you cannot do some things, but you had seen that yet. But, because of the new pointer tail, you have its much easier to delete the last Node (see below).
Please, change all your attributes to private and code a getter and a setter for each of them. For example in the class Node for the attribute next:
private Node next;
// other code...
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
I have solved the problem with "delete Node First and delete Node Last" in the following way:
public class DoublyLinkedList {
private Node head; // begin
private Node tail; // end
public void deleteFirstElement() {
if (!isEmpty()) {
head = head.getNext();
}
}
public void deleteLastElement() {
if (!isEmpty()) {
tail = tail.getPrev();
}
}
// other code
}
Of course, you have to proof your other code, if it works. I hope that I could help you.
I'm trying to better undserstand my teachers notes on how to delete a node from a doubly linked list, what she had on the boards is
public void deleteNode(Node D){
Node current = head;
while(current.data != D.data && current.next != null){
current = current.next;
}
d.prev.next = d.next;
d.next.prev = current.prev.
}
I can't help but feel like this isn't enough to remove a node. I was thinking maybe she meant
current.prev.next = d.next and
current.next.prev = d.prev
Once I figure out how to understand this better would it make sense if I wanted to delete a node from the middle by doing
public void deleteMiddle(){
Node current = head;
int i = 0;
while(i < size/2){
current = current.next;
i++;
}
deleteNode(current);
}
The correct way would be to either pass in the value, i.e. the data, or to make the method private, to protect against misuse.
Or do both:
public void deleteNode(int data) {
Node current = head;
while (current != null && current.data != data) {
current = current.next;
}
deleteNode(current);
// Note: We silently do nothing if 'data' not found
}
private void deleteNode(Node node) {
if (node != null) {
// Here we can rely on 'node' actually being in our list
if (node.prev != null)
node.prev.next = node.next;
else
head = node.next;
if (node.next != null)
node.next.prev = node.prev;
else
tail = node.prev;
}
}
the method 'insertAscending' only gives me the first number even after i enter new ones. can anyone help with what i'm doing wrong? Thanks.
public class LinkedList13 {
// Private inner class Node
private class Node{
int data;
Node link;
public Node(){
data = Integer.MIN_VALUE;
link = null;
}
public Node(int x, Node p){
data = x;
link = p;
}
}
// End of Node class
public Node head;
public LinkedList13(){
head = null;
}
public void insertAscending(int data){
Node node = new Node();
node.data = data;
if (head == null)
head = node;
Node p = head;
while (p.link != null)
{
if (p.link.data > data)
{ node.link = p.link;
p.link = node;
break;
}
p= p.link;
}
}
}
Hint: is (p.link != null) ever true?
First of all, you should return after setting the head of the list (when the first element is added).
Second of all, you should handle the case where the newly inserted node is the smallest in the list (and therefore should come first). Your loop never compares the added node to the head of the list.
Finally, if the added element wasn't inserted in the while loop, it should be inserted after the while loop.
public void insertAscending(int data)
{
Node node = new Node();
node.data = data;
if (head == null) {
head = node;
return;
} else if (node.data < head.data) {
node.link = head;
head = node;
return;
}
Node p = head;
boolean added=false;
while (p.link != null)
{
if (p.link.data > data)
{
node.link = p.link;
p.link = node;
added = true;
break;
}
p = p.link;
}
if (!added)
p.link = node;
}
Check out your if condition if(p.link.data > data) the only way a node gets into the list is when that is true. This means, that, if the value of data being inserted it greater than (or equal to) everything that's been inserted so far, it will be discarded.
An easy way to fix this is change break to return and add p.link=node at the end (after the loop).
I'm working on a method that is supposed to delete the node prior to the last one,the logic seems quite fine with me, but when I tried to implement it in a project, it didn't work out. ( Oh and I'm using MyLinkedList)
here's the code:
public void deleteSec(){
Node current = head;
Node p = head.next;
Node q = null;
while(p.next!=null){
q = current;
current.next = p;
p = p.next;
}
q.next = p; // q.next = q.next.next;
}
What if your LL is empty? head will be null and this will cause an exception when you call head.next;
you have to take care of special cases like: empty LL, LL with one node, LL with two nodes.
Here is my code:
public void deleteSec() {
if (head == null) {
return;
}
if (head.next == null) {
return;
}
if (head.next.next == null) {
head = head.next;
return;
}
Node current = head;
Node p = current.next;
Node q = p.next;
while (q.next != null) {
current = current.next;
p = p.next;
q = q.next;
}
current.next = q;
}
if(myLinkedList.size() > 1) {
myLinkedList.remove(myLinkedList.size()-2);
}
well i personally compiled it,
Assuming the node class is named Node and you have a getNext() method that returns the next Node or null if this Node is the last node, you would do something like this.
if (head == null) // or if (first == null)
{
return; // There are no elements in the list.
}
Node currect = head; // This is the head, or Node current = first;
Node previous = null;
while (current.getNext() != null)
{
previous = current;
currrent = current.getNext();
}
Then do this to make the second to last pointer to next null.
if (previous != null)
{
previous.setNext( null );
}
else
{
// The list has 1 entry only.
head = null; // or first = null;
}
If deleting a second last node would be a common operation, as it is in my case, I would suggest an extra prev or previous node added to the Node construction.
Usually a linked list node would be
private static class Node<Item> {
private Item item;
private Node<Item> next;
}
But I modified it to be like
private static class Node<Item> {
private Item item;
private Node<Item> prev;
private Node<Item> next;
}
Thus, if you want to delete the second last, the implementation would be pretty straightforward:
oldSecondLast = last.prev; // Assumes last points to the last node
oldSecondLast.next = last;
last = oldSecondLast.prev;
oldSecondLast = null; // To avoid loitering
My problem is: Given a function to reverse a linked list.
My attempt at it in C was:
ListNode *reverse(ListNode *head)
{
if(head == NULL || head->next == NULL)
return head;
ListNode *temp = head->next;
ListNode *retP = reverse(temp);
temp->next = head;
head->next = NULL;
return retP;
}
But I do not think this is right. I want to be able to do it in Java and I am stumped on this. Any help would be appreciated. Please help me get started
If you want to reverse a List in Java, use
Collections.reverse(List list)
If you want to know how it is implemented or want to do it by hand, have a look at the JDK sources of java.util.Collections.
Iteratively
public reverseListIteratively (Node head) {
if (head == NULL || head.next == NULL)
return; //empty or just one node in list
Node Second = head.next;
//store third node before we change
Node Third = Second.next;
//Second's next pointer
Second.next = head; //second now points to head
head.next = NULL; //change head pointer to NULL
//only two nodes, which we already reversed
if (Third == NULL)
return;
Node CurrentNode = Third;
Node PreviousNode = Second;
while (CurrentNode != NULL)
{
Node NextNode = CurrentNode.next;
CurrentNode.next = PreviousNode;
/* repeat the process, but have to reset
the PreviousNode and CurrentNode
*/
PreviousNode = CurrentNode;
CurrentNode = NextNode;
}
head = PreviousNode; //reset the head node
}
Recursively
public void recursiveReverse(Node currentNode )
{
//check for empty list
if(currentNode == NULL)
return;
/* if we are at the TAIL node:
recursive base case:
*/
if(currentNode.next == NULL)
{
//set HEAD to current TAIL since we are reversing list
head = currentNode;
return; //since this is the base case
}
recursiveReverse(currentNode.next);
currentNode.next.next = currentNode;
currentNode.next = null; //set "old" next pointer to NULL
}
Source, with explanation (after using google for 3 seconds) http://www.programmerinterview.com/index.php/data-structures/reverse-a-linked-list/
public Node reverse(Node node){
Node p=null, c=node, n=node;
while(c!=null){
n=c.next;
c.next=p;
p=c;
c=n;
}
return p;
}