Insert into LinkedList Alphabetically - java

I am attempting to insert people alphabetically into a linked list by lastName. I have one really weird issue. The code as you see it works fine, except the list is in reverse order. What I can not figure out is why when I use the line of code:
current != null && lastName.compareTo(current.lastName) >= 0)
to insert people into my list, instead of adding over 100 people I add 6. Yet like I said above I can do it in reverse order no problem. What is up with that?
public void insert(String firstName, String lastName, String time,String show, String command,int section){
PeopleNode newNode = new PeopleNode(lastName,firstName,time,show,command,section);
size++;
PeopleNode previous = null;
PeopleNode current = head;
while(current != null && lastName.compareTo(current.lastName) <= 0){
previous = current;
current = current.next;
}
if(previous == null){
head = newNode;
}else{
previous.next = newNode;
newNode.next = current;
}
}

I guess the compareTo method works the other way round for Strings, so maybe try
while(current != null && current.lastName.compareTo(lastName) <= 0)
But I recommend you to use just the Compareable interface and sort the list by using Collections.sort(yourlist)

Let's say you have "b", "c", "d" and "a" as the last names. If you insert in that order, for the first three nodes it will be:
b -> c -> d
When you try to insert a, it will not enter the while loop. So, "previous" will be null. It will enter the first if condition and set the head as the new node, i.e. "a", and it will exit the method. Next of the head is not set.
So you have a broken list with only the "a" node at the end.
I did not try this but this seems to be the problem.

Ok I figured it out!
if(previous == null){
head = newNode;
}else{
previous.next = newNode;
newNode.next = current;
}
The line:
newNode.next = current;
needs to be outside of the else statement!

Related

Circular Doubly Linked List Java - Explanation

at the moment, I am programming a circular doubly linked list and my task is completed, but I have a slight problem in understanding the code 100%.
This is the code:
if (counter == 0) {
startpoint = newNode;
startpoint.next = startpoint;
startpoint.prev = startpoint;
head = startpoint;
currentNode = newNode;
} else {
newNode.prev = startpoint.prev;
newNode.next = startpoint;
startpoint.prev.next = newNode; <- this is, where I have problems
startpoint.prev = newNode;
head = startpoint;
currentNode = newNode;
}
counter++;
}
The first part is completeley clear and just describes, that the first node (if there is no other node) is going to point on itself, when the next or first-method is called. After the else-statement, the first line describes that the first node can point to the second and the second to the previous node, right?
The second line after else just describes, that the last node points onto the first one. The fourth line than describes, that the first node points onto the last node, if the prev-method is called and so the circle is closed. But what exactly does the third line describes? The code definitely works.
Thank you for your time!
Greets
Dominik
Your list is circular.
startpoint.previs the element before the startpoint, so it's the last element of the list.
Let's take an example, this is your list: A>B>C, you try to add D.
This line: startpoint.prev.next = newNode; will link the current last element (C as A.prev == C) to your new element. (C.next = D)
this line startpoint.prev = newNode; will set the new element as the last element of the list (A.prev = D).
The code inserts newNode just before startpoint. The 3rd line of the else statement simply updates the node before the startpoint so that it's next field references the new node.
To make it more clear, one can rewrite the line like this:
Node nodeBeforeStarpoint = startpoint.prev;
nodeBeforeStartpoint.next = newNode;

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.

How to reverse LinkedList in 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

Delete last node, or only node from a Linked List in Java.

I am unable to get my program to delete the last node or only node in my linked list. It will delete any other node. This program allows the user to enter integers and delete them. Thanks in advance for your help.
// This method finds the value requested in the Linked List.
public Node find(Node head, Comparable value2){
if (head == null )
{
System.out.println("The list is empty");
return null;
}
Node pointer = head;
while (pointer != null)
{
if (pointer.data.compareTo(value2)>=0)
{
Node delNode = pointer;
System.out.print("Found it. Deleting " + delNode.data + "\n");
return delNode;
}
pointer = pointer.next;
}
return null;
}
// This method deletes a given value from the linked list.
public void delete(Node head, Comparable value2){
Node delNode;
delNode = find(head, value2);
if (delNode== null)
{
System.out.println("The value: " + value2 + " does not exist");
print(head);
}
else
{
if (delNode.next == null)
{
System.out.println("Trying to delete last");
delNode = null;
print(head);
}
else{
delNode.data = delNode.next.data;
Node temp = delNode.next.next;
delNode.next = null;
delNode.next = temp;
print(head);
}
}
return;
}
I thought that if (delNode.next== null) {delNode = null} would do it?
If you want to delete a node, you should have a reference to the node before the one you want to delete, say beforeNode, and set
beforeNode.next = beforeNode.next.next;
(Think about special cases like deleting the last element.)
See Java Linked List search and delete method
Please note that in the sequence
delNode.next = null;
delNode.next = temp;
The first line is useless.
You current delete operation effectively works by copying the next node into the current node and then deletes the next node, making it look like you deleted the current node. This is fine until there is no next node, as you have discovered.
The reason the following doesn't work
if (delNode.next == null)
{
System.out.println("Trying to delete last");
delNode = null;
print(head);
}
is that delNode is just a local variable, setting delNode to null doesn't affect anything outside of delete().
If you want to delete the last node from the list, you need to set the next pointer in the second last element to null. Therefor it is insufficient for find() to simply return the element you wish to delete -- you need the previous element.
Pseudocode for delete(data) should be (untested):
if head == null
return
if head.data == data
head = head.next
return
previous = find_previous(data)
if previous == null
return
previous.next = previous.next.next

Categories