JAVA Linked List :method to insertLast - java

I have my code as following:
Node current=head;
if(current==null)//check
else{
while(current.getNext()!=null)
current=current.getNext(); //loop through to find the last node in the list
}
//if I find it then connect it with my newNode(add)
Node add=new Node("A");
current.setLink(add);
add.setLink(null);
But it does not work, I drawn a diagram but still have no idea what`s wrong with it.

the line
if(current==null) //why do you check if you don't have any statements afterwards?
this solution is for singly linked list:
public static Node addLast(Node head, Object x) {
// save the reference to the header so we can return it.
Node ret = head;
// check base case, head is null.
if (header == null) {
return new Node(x, null);
}
// loop until we find the end of the list
while ((head.next != null)) {
head = head.next;
}
// set the new node to the Object x, next will be null.
head.next = new Node(x, null);
return ret;
}

Related

Implementing an AddAtIndex method in a LinkedList

currently, I am working on implementing an AddAtIndex method and for the most part it seems to be working fine. However, my method is not passing my JUnit test and I can't seem to understand why. Thus, I have chosen to show the code I have done thus far:
**
* Add an element to the list at the specified index
* #param The index where the element should be added
* #param element The element to add
*/
public void add(int index, E element ) //Method should be O(1) time.
{
// TODO: Implement this method
if (index < 0) {
System.out.println("Can't add an element at a negative index.");
}
int i = 0;
LLNode<E> currentNode = head.next;
while ( i < size ) {
if ( i == index ) {
LLNode<E> newNode = new LLNode<E>(element);
LLNode<E> tempNode = new LLNode<E>(currentNode.data);
currentNode.next = tempNode;
currentNode.data = newNode.data;
newNode.prev = currentNode.prev;
newNode.next = tempNode;
tempNode.prev = newNode;
size++;
}
currentNode = currentNode.next;
i++;
}
}
My thought process behind the code is that the method creates a new Node, then it replaces the data at the specified index of the linked list. However, the data at the node it is replacing is stored in a temporary node which is incremented in position to the next node after the new node. I am about 80% confident in my implementation though the code looks a bit sloppy. I have created a driver to demonstrate the implementation. The drivers code is as follows:
public class LinkedListDriver {
public static void main(String[] args) {
// TODO Auto-generated method stub
MyLinkedList<String> nameList = new MyLinkedList<String>();
nameList.add("Hamadi");
nameList.add("Ballo");
nameList.add(1, "Salisu");
nameList.add(2, "Galo");
System.out.println(nameList.toString());
System.out.println(nameList.size());
nameList.set(2, "Abdullahi");
System.out.println(nameList.toString());
nameList.remove(1);
System.out.println(nameList.toString());
MyLinkedList<Integer> list1 = new MyLinkedList<Integer>();
list1.add(65);
list1.add(21);
list1.add(42);
System.out.println(list1.toString());
list1.remove(0);
System.out.println(list1.toString());
}
}
The Output from the driver is as follows:
List: Hamadi, Salisu, Galo, Ballo,
4
Replacing Galo with Abdullahi
List: Hamadi, Salisu, Abdullahi, Ballo,
Removing Salisu from the list
List: Hamadi, Abdullahi, Ballo,
List: 65, 21, 42,
Removing 65 from the list
List: 21, 42,
The unit test fails however with the following error:
It fails at the AssertEquals method:
shortList.add(2, "E");
shortList.add(3, "F");
**assertEquals("AddAtIndex: at position 2 ", "E", shortList.get(2)); //fails here**
assertEquals("AddAtIndex: at position 3 ", "F", shortList.get(3));
assertEquals("AddAtIndex: List size is ", 6, shortList.size());
I would like to know what I'm doing wrong. I have this literally completely figured out, though I know that there is something a bit off about my AddAtindex method. Thanks!
You don't need that tempNode. Just create the newNode and insert it properly between currentNode and its previous node.
You should also consider the possibility of adding an element at the beginning (no previous) or end (no next) of the list.
I used head and tail as sentinel nodes. Created a new node to be added in the list.
public boolean add(E element) {
// create new element
LLNode<E> variable = new LLNode(element);
variable.next = null;
variable.prev = null;
// if element is null, throw exception
if (element == null) {
// return false;
throw new NullPointerException("Element is null");
} else {
// get the value stored in tail.prev in variable temp.
variable.prev = tail.prev;
variable.next = tail;
// now modify the tail node prev and new node next
tail.prev = variable;
// get prev node next link changed
variable.prev.next = variable;
// update size
if (head.next.next != tail) {
size++;
}
return true;
}
}

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.

Linked Lists. Head and Tail References

Im trying to make an Add and Delete method to my linked list class. I made 2 references with the names Head and Tail.
Head -> 1 -> 2 -> 3 -> Tail:null
I keep getting problems when I try and delete specific nodes because Java says I'm out of bounds. I think it is because my Head isn't pointing to the first Node? What do you guys think? Or am i going about this the total wrong way...
public class LinkedList{
private Node head;
private Node tail;
private int listCount;
public LinkedList()
{
head = new ListNode(null);
tail = new ListNode(null);
listCount = 0;
}
public void add(Object elem){
ListNode newNode = new ListNode(elem);
if (size() == 0){
newNode = head;
tail = head;
}
newNode.setLink(tail);
tail = newNode;
listCount++;
}
public Object delete(int index)
// post: removes the element at the specified position in this list.
{
// if the index is out of range, exit
if(index < 1 || index > size())
throw new IndexOutOfBoundsException();
ListNode current = head;
for(int i = 1; i < index; i++)
{
if(current.getLink() == null)
throw new IndexOutOfBoundsException();
current = current.getLink();
}
current.setLink(current.getLink().getLink());
listCount--; // decrement the number of elements variable
return current.getInfo();
}
public int size() {
return listCount;
}
}
public class Node {
private Node link;
private Object info;
public Node(Object info)
{
this.info = info;
link = null;
}
public void setInfo(Object info)
{
this.info = info;
}
public Object getInfo()
{
return info;
}
public void setLink(Node link)
{
this.link = link;
}
public Node getLink()
{
return link;
}
}
I think it's because your head never links to anything. What I would do to fix it is in your add method, check the size of your list; if it's 0, set the head to the new element and set the tail equal to the head. If it's 1, link the head to the new node and set tail. If it's 2, just set the tail's link to the new node and set the tail (like you have now).
Also, I'm not sure how you implemented it, but newNode.setLink(tail); seems wrong...the tail should be linked to newNode. From the way it looks, it seems like you're trying to do newNode -> tail
EDIT: Ok, here is why I would try
public void add(Object elem){
ListNode newNode = new ListNode(elem);
if (size() == 0){
newNode = head;
tail = head;
}else if(size() == 1){
head.setLink(newNode);
tail = newNode;
}else{
tail.setLink(newNode);
tail = newNode;
}
listCount++;
}
Looks like you did not initialize the link from head to tail when you set up your initial (empty) linked list.
Ok. Here is a strategy to use when working with singly linked lists (forward link only). You need to determine what actions will be allowed on the list (e.g. add/remove from head or tail only?; or add and remove nodes anywhere in the linked list (bringing the list back together once you have cut a node out). If you will be allowing nodes to be deleted from anywhere, then you will need to have a way of UNIQUELY identifying each node (so you can unambiguously determine the node that will be deleted). You may also want to be able to add a node before or after some other node . and uniqueness may be needed for that. If you do NOT care which value you delete or add before/after then you can relax the uniqueness constraint.
Now for strategy to implement. Start with a head (initially null).
To add a node, walk down your linked list until you find a null next link. Replace that with your node, and have your nodes forward link set to null. (Efficiency improvement, have a tail that always has the last node in the linked list, or null if there is nothing in the list).
To delete a node, walk your list until you find the node you want to delete, change the previous link to the link in the node to be deleted (you are now done)
To add a node at the end of the list, go to the link pointed to by tail (if null, list is emplty); change its link to your node, ensure your new node has a null in its link; and set the tail to your node
To count size of linked list, either walk your tree and count (or, for computational efficiency, keep a running size that is incremented or decremented when you add or delete a node.
Does this help?
Look at this link for a full description!

Linked lists - Can't figure out why this remove last function is not working?

I made this remove last function and it seems like it should work, but when I call it, it doesn't actually remove anything, all of the nodes are still there.
Is there any problem with it?
public Object removeLast()
{
Node currentNode;
currentNode = this.getHead();
while(currentNode != null)
{
if(currentNode.getNext()==null)
{
currentNode = null;
return null;
}
currentNode = currentNode.getNext();
}
return null;
}
You have a list which contains nodes. Each node contains a pointer to the next node.
To remove a node from the list, you have to set the next pointer of the previous node to null
If you also have a pointer to the previous element, this is trivial. Something like:
public Object removeLast()
{
Node currentNode;
currentNode = this.getHead();
while(currentNode != null)
{
if(currentNode.getNext()==null)
{
// The line below is changed!!!
currentNode.getPrevious().setNext(null);
return null;
}
currentNode = currentNode.getNext();
}
return null;
}
If you have a pointer in each node to the next as well as the previous node, then we call this a doubly-linked-list.
Also, there's no need for the return type to be Object, you can change your method signature to:
public void removeLast()
And then change each of your return null; to return;
What you do now is that you set your dummy node to null, but that does not effect your list at all. I'll try to visualize:
Your original list consists of nodes, connected by next-pointers. The local variable currentnode refers to one of the nodes in the list. Below, it points to the last element.
head --<next>-> node --<next>-> node --<next>-> node --<next>-> null
^
|
currentnode
If you now do currentnode = null, this yields:
head --<next>-> node --<next>-> node --<next>-> node --<next>-> null
currentnode --> null
Note that this does not affect your linked list at all.
What you want to do instead is set the --<next>-> of the one-but-last node to null. For this, you should keep track of the previous node while iterating your list:
if (getHead().getNext() == null) {
setHead(null);
} else {
Node previous = getHead();
Node current = previous.getNext();
while (current.getNext() != null) {
previous = current;
current = current.getNext();
}
previous.setNext(null);
}

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