How to reverse LinkedList in java - java

Please accept my apologies first, but I could not reverse my Linked List in java..
I have class and inner class:
MyList{
class Element{
private Element next;
public Element getNext(){return next;}
}
public void reverseMyList(Element curr) {
if (curr.next == null) {
head = curr.next;
return;
}
reverseMyList(curr.next);
while (curr.next != null) {
curr.next.next = curr.next;
curr.next = null;
}
}//:~
I need to reverse my List, I am using method reverseMyList, which needs Element curr.
If my way of thinking in this case is correct ?
Thank you in advance!

Since this kinda looks like homework, I'm not going to lay out the entire solution here, but I will explain how you should conceptually do it.
Imagine that you have 2 linked lists. You have your input list that you need to reverse, and you have an empty one.
If you keep taking the first element off of the original list, and keep putting that on the front of the new list until your original list is empty, than your new list will be what the original was, except reversed.

public static void Reverse(Element element)
{
Element current = element;
Element next = current.Next;
Element nextToNext;
var first = current;
while (next != null && next.Next != null)
{
nextToNext = next.Next;
next.Next = current;
current = next;
next = nextToNext;
}
if (next != null)
{
next.Next = current;
}
first.Next = null;
}

the method you are looking for already exist in package java.utils:
Collections.reverse(mylist);
this method will change the order of element direcly inside your list and you dont need to instance a new list-object... here you can find more specified documentation

Related

Algorithm: Merge Sort with linked list missing items

I am trying to sort my linked list with merge sort. The list is actually sorted but it is kind of missing first item(s).
Merge sort functions:
public Node mergeSort(Node head) {
if (head == null || head.next == null) {
return head;
}
Node middle = middleElement(head);
Node nextofMiddle = middle.next;
middle.next = null;
return merge(mergeSort(head), mergeSort(nextofMiddle));
}
public Node merge(Node left, Node right) {
Node temp = new Node();
Node newHead = temp;
while (left != null && right != null) {
if (left.info <= right.info) {
temp.next = left;
temp = left;
left = temp.next;
} else {
temp.next = right;
temp = right;
right = temp.next;
}
}
temp.next = (left == null) ? right : left;
return newHead;
}
public Node middleElement(Node head) {
if (head == null) {
return head;
}
Node slow = head;
Node fast = head;
while (fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
So I printed the list to the screen using traverse:
public static void main(String[] args) {
MyLinkedList mll = new MyLinkedList();
mll.insert(3);
mll.insert(5);
mll.insert(9);
mll.insert(1);
mll.insert(8);
mll.insert(7);
mll.insert(2);
mll.mergeSort(mll.head);
mll.traverse();
}
I have result like this:
1 and 2 missing!
After checking, i noticed that the "tail" of the linked list value is still 2. I don't know why can someone help?. I'm really new to programming so sorry for any inconvenience. Thank you for reading!
You're not far from a correct solution. I was able to get a working sort by adding 1 line and changing 3.
Your merge isn't doing what you think it is.
Allocating a false head node (what you call temp, not a good choice of name; try falseHead) is a fine idea. Then falseHead.next is the true head. That's what you'll finally return as the sorted list. Note that initially it's null, which is what you'd expect.
What you're missing is a variable tail to reference the current last node in the merged list. Since there is initially no last node at all, this should be initialized equal to falseHead. Consequently, when you append the first element to the tail of the current result by setting tail.next, you'll also be setting falseHead.next, i.e. creating the head element. It all works out.
Now, what is the logic for, say, removing the current head of the right list and appending it to the merge result? It's just 3 steps:
Do the append operation by making tail.next the current head of right.
Update tail to tail.next.
Remove the head of right by updating right to right.next.
Of course the left side is similar.
Good luck. You're close.
You have a couple problems that I can see. One, mentioned by #rcgldr, in the comments is that you merge method is returning the temp node newHead, but that node was no value and is not part of your graph. You need to return it's child newHead.next.
The other problem is that you never reset the head of your list. So after all the sorting, the head of mll still points to the original head, which in this case is 3. So when you traverse the list you skip 1 and 2. I'm not sure what your linked list class looks like but something like this should be close -- just assign the final node returned by mergeSort to the head of the list. Then when you traverse you should be starting in the right spot:
mll.head = mll.mergeSort(mll.head);
mll.traverse();

Deleting a node in a linked list with void return statement [Java]

I'm trying to a do an assignment to delete a node in a Linked list. I have the front node deletion to work, and to return when the friendList is null. firstFriend is a Friend object that has a Person in memory and points to another friend. This method removes a friend from the firstFriend linked list. I'm struggling with how to update firstFriend properly within the method
public void removeFriend(Person friend){
Friend prev = null, curr = firstFriend, front = firstFriend;
if (curr == null){
return;
}
while(firstFriend != null){
if(friend.equals(curr.who)){
if(prev == null){
firstFriend = firstFriend.nextFriend;
return;
}
else{
prev = curr.nextFriend;
}
prev = curr;
curr = curr.nextFriend;
}
firstFriend = front;
return; // replace this line
Hint #1: you only ever need to update firstFriend when you are deleting the first Friend on the list
Hint #2: separate the problem of removing a Friend into the two parts of 1) finding the Friend node that points to the Person you want to remove and 2) actually removing the Friend, instead of trying to do everything at once.

Create new Node for Singly Linked List in Java

I am still learning Java, and currently working problems from Cracking the Coding Interview, and one of the problems on Chapter-2 (LinkedList) asks to remove duplicates from an unsorted linked List. I found a bunch of answers/solution on GitHub, but I would like to create my own Node, and write my own version.
What I have implemented so far is that I created Node class and write the function/method that can remove the duplicates from unsorted LinkedList, but when I try to test it, I tried to create the LinkedList in the main function, but I still have no idea how to figure it out. Can someone please help/guide me how to create a Singly LinkedList?
Basically, I create four nodes (fourth,third,second,head), and connect them all using the Node class.
Thanks in advance,
public class Node {
int data;
Node next;
public Node(int data, Node next){
this.data = data;
this.next = next;
}
public String toString(){
return data + "";
}
}
public class problem1 {
public void Remove_duplicates(Node head){
if(head == null){
return;
}
Node current = head;
while(current != null){
Node runner = current;
while(runner.next != null){
if(runner.next.data == current.data){
runner.next = runner.next.next;
}
else {
runner = runner.next;
}
}
current = current.next;
}
}
public static void main(String[] args) {
Node fourth = new Node(5,null);
Node third = new Node(3,fourth);
Node second = new Node(4,third);
Node head = new Node(3,second);
for(Node a: head){
// ERROR: saying can only iterate over an array (or) java.lang.Iterable
System.out.println(a.toString());
a = a.next;
}
}
}
Try another kind of loop e.g. while
Node head = new Node(3, second);
Node node = head;
while (node.next != null) {
System.out.println(node.toString());
node = node.next;
}
Like it explains it does not know how to iterate over your nodes.
Another approach for using the foreach would be to create an own class which implements the interface Iterable and does contain your LinkedList logic.
For the second approach I would suggest you to read the following: How can I implement the Iterable interface?

Converting a linkedlist to binary tree

I've a linked list that has two links - next and another assume. Initially, all another hold null. Now, I'm trying to convert this to a binary tree with next holding the liftChild and another holding rightChild. However, I want to do this in O(n) and in constant space. I've tried a lot. Below is my code. I'm verifying the result by level-order traversing the resulting tree. Currently, I know what's the mistake but don't know how to solve it. The mistake here is that inside the while loop, I'm changing the links of the node properly, but this means I cannot do node = node.next at the end because node's next is already pointing somewhere ahead in the list. So, I don't know how to traverse every node. Any hint, help is appreciated. Not hw, not interview question or anything. Just trying to learn data structures. So, this tree and ll stuff!
public class LlToBt {
public SpecialNode llToBt(SpecialNode node) {
SpecialNode temp = node;
SpecialNode returnNode = node;
if(node == null)
return null;
if(node.next == null)
return node;
node = returnNode;
while(node != null) {
SpecialNode currentNode = node;
temp = temp.next;
if(temp == null) {
//node.next = null;
//node.another = null;
return returnNode;
}
node.next = temp;
temp = temp.next;
if(temp == null) {
//node.next = null;
//node.another = null;
return returnNode;
}
node.another = temp;
node = currentNode.next;
}
return returnNode;
}
}
If you are changing the link that you will want to traverse before you traverse it, then you need to store off in a different variable the result of the traversal before you change the link. Then after the change, you can traverse using your temporary copy.

How do you remove nodes from a linked list?

I have a linked linked of student objects. It's basically a database that stores data about students as student objects. The only problem I am having is creating the removeStudent method. Posted below is what I have tried so far, altering different parts of it to see if a different result occurs. Right now with this code, I can delete a student in my driver, but it will also delete every student before the one that I want to delete as well, leaving behind only the students that are in the database after the student that I am trying to delete.
public void RemoveElements(Object Student) {
LinearNode<Object> current = element;
LinearNode<Object> temp = current;
while (current.getNext() != null) {
temp = current;
current = current.getNext();
if(current.getElement() == Student) {
temp.setNext(current.getNext());
length--;
}
}
}
public void RemoveElements(Object Student) {
LinearNode<Object> current = element;
LinearNode<Object> previous = null;
//LinearNode<Object>(student);
while (current.getNext() != null) {
current = current.getNext();
if(current.getElement() == Student) {
length--;
element = element.getNext();
if (previous != null) {
previous.setNext(element.getNext();
} else {
//if you have a pointer to the head element place it element.getNext();
}
}
previous = current;
}
}
If the current contains the object to be removed, you need get a reference to the previous node, and point it at the next node. So you have
A -> B -> C
and B contains the item to be removed, you want your linked list to look like
A -> C
A few things are wrong with your code
1) You are not doing the above
2) You are not setting previous within your while loop. You can do that right before
current = current.getNext();
3) For the code
LinearNode<Object> current = element;
at the top, what is element?
It looks like element is the head of the list. Look at the code that changes element and change it so that when you delete the second item, element still points to the first element and the first element points to the third instead of the second.

Categories