Reversing a linked list - java

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

Related

How can I add it delete Node First and delete Node Last

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.

How to delete the first node of doubly linked list

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

Return the deleted node in java RECURSIVELY

I learned most of the linked data structures using C++ where there is pass by reference available to you and recursion is pretty straightforward. I recently switched to Java and I always get confused with the recursive versions of these structures.
I wanna take the node out of the list. But I want to return the node. When I return the deleted node from the else if branch, it expectedly messes up the list. But I can't see a way around it.
public node deleteval (int val){
node prev = head;
head = deleteval(head,prev,val);
return head;
}
private node deleteval(node head,node prev, int val){
if(head == null){
return null;
}
else if (head.value == val){
prev.next = head.next;
node deleted = head;
head = prev;
return head.next;
}
prev = head;
head.next = deleteval(head.next,prev,val);
return head;
}
This is not a homework, just trying to understand. Thanks for any input.
To delete a node you only need to do prev.next = head.next and handle the edge case for root node. There is no need for a stack or any other supporting data structure, you simply recurse deeper into the list until you find the value or reach the end.
private Node root;
public Node deleteVal(int val) {
return deleteRec(root, null, val);
}
private Node deleteRec(Node head, Node prev, int val) {
if (head == null) {
return null;
}
if (head.value == val) {
if (prev != null) {
prev.next = head.next; // deleting non-root node
} else {
root = null; // deleting root node
}
return head;
}
return deleteRec(head.next, head, val);
}

Deleting the second last node from a LinkedList in java

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

Removing duplicates from a linked-list in Java without the use of extra buffer

I am reviewing some snippets of code for an upcoming test. I saw this in my notes, and just now realized that this code for method 1 doesn't actually remove duplicates if the list is in this way A -> B -> C -> A. I wrote an alternative function (method 2) that I think will actually work. What do you guys think? Does method 1 actually not work, and I'm tracing it wrong? p.s. We are not allowed compilers at this time :)
Here is the code, and a short introduction of what it should do.
METHOD 1: What I think doesn't work when there are 2 exact things at the head and tail.
Write code to remove duplicates from an unsorted list WITHOUT a buffer. Wwe can iterate with two pointers: “current” does a normal iteration, while “runner” iterates through all prior nodes to check for dups. Runner will only see one dup per node, because if there were multiple duplicates they would have been removed already.
public static void deleteDuplicates1(LinkedListNode head) {
if (head == null) return;
LinkedListNode previous = head;
LinkedListNode current = previous.next;
while (current != null) {
LinkedListNode runner = head;
while (runner != current) { // Check for earlier dups
if (runner.data == current.data) {
LinkedListNode tmp = current.next; // remove current
previous.next = tmp;
current = tmp; // update current to next node
break; // all other dups have already been removed
}
runner = runner.next;
}
if (runner == current) { // current not updated - update now
previous = current;
current = current.next;
}
}
}
I was thinking this would work.
METHOD 2:
public void removeDuplicates2(){
Node current = null;
Node tracer = null;
for( current = head.next; current!=null; current=current.next){
for(tracer=head; tracer!=current; tracer=tracer.next){
if(tracer.data == current.data)
//DELETE THE NODE IN CURRENT
}
}
}
The best way is sort the linked list. then iterate and check if adjacent elements are the same. If yes, delete the adjacent element. This is an O(nlogn) method without using an extra buffer.
I'm not sure what "without an extra buffer" means to you, but since I'm a lazy person and since I think other people are far better at writing out algorithms than me, I'd put the whole linked list into a HashSet and back to a linked list. That will remove duplicates easily:
LinkedList result = new LinkedList(new HashSet(inputList));
Or, if you want to preserve the order of elements
LinkedList result = new LinkedList(new LinkedHashSet(inputList));
Now since this is a homework question and you seem to be implementing a LinkedList yourself, it may well be that this solution is not viable ;-) But in any case, it will be of O(n) complexity, and not O(n^2) like both your methods 1 and 2, which might already be a lot better for you...?
I have added my code here but I am confused about the time complexity will it be O(n) or O(nlogn)? Let me know about this.
public Node removeDuplicatesFromUnsortedLinkedListWithoutExtraSpace(Node head)
{
if(head == null || head.next == null)
return head;
Node prev = head;
Node curr = head.next;
Node temp = curr;
while(prev.next!=null)
{
if(prev.data == curr.data)
{
temp.next = curr.next;
curr = curr.next;
}
else
{
if(curr != null)
{
temp = curr;
curr = curr.next;
}
if(curr == null)
{
prev = prev.next;
curr = prev.next;
temp = curr;
}
}
}
return head;
}
Modification made to the function above to rectify the logic
But i am not sure what is the time complexity of the function. Is it O(n^2) or O(n)
public static Node removeDuplicatesFromUnsortedLinkedListWithoutExtraSpace(Node head){
if(head == null || head.next == null)
return head;
Node prev = head;
Node curr = head.next;
Node temp = prev;
while(prev.next!=null){
if(curr != null){
if(prev.data == curr.data){
temp.next = curr.next;
curr = curr.next;
}else {
temp = curr;
curr = curr.next;
}
}else{
prev = prev.next;
curr = prev.next;
temp = prev;
}
}
return head;
}
public static Node removeDuplicates(Node head) {
Node cur = head;
Node next = cur.next;
while (cur != null && cur.next != null) {
next = cur;
while (next.next != null) {
if (cur.data == next.next.data) {
Node d = next.next;
next.next = next.next.next;
} else {
next = next.next;
}
}
cur = cur.next;
}
return head;
}
This uses the double pointer method. Without using any extra space, we can have two points cur(Slow) and next(Fast) pointers. For each cur pointer the data in the next pointer is checked. If a match is found then the pointers are adjusted to point to the next respective node. Hope this helps.

Categories

Resources