Can somebody help me fix this issue with the code that I wrote?
When I run it doesn't print out the values of the linked list. I don't understand what is the problem, the compiler keeps giving a blank screen when I run the code.
public class Node {
int data;
Node next;
public static void main (String Args [])
{
Link object = new Link ();
object.insert(15);
object.insert(30);
object.insert(50);
object.insert(70);
object.show();
}
}
public class Link {
Node head;
void insert (int data)
{
Node node = new Node();
node.data=data;
if (head == null)
{
node=head;
}
else
{
Node n = head;
while (n.next != null)
{
n=n.next;
}
n.next=node;
}
}
void show ()
{
Node n = head;
while (n != null)
{
System.out.println(n.data);
n=n.next;
}
}
}
Your code is doing this:
if (head == null)
{
node=head;
}
This sets the null in head into the variable node. You aren't setting the value of head.
You should be doing this (setting the value of node into the variable head):
if (head == null)
{
head = node;
}
In your Link class, you need to change the following:
if (head == null)
{
node=head; //<-- change this to head = node;
}
¿Do you have to do it by that way? Java has already a LinkedList utility, makes it easier.
Related
I have written my own linked list and am reading integers from a file into the list and printing them out. However, only the head of my list is printing and nothing else. I've been staring at this code for so long I feel insane, can anyone help?
Method in a separate 'files' class that reads in a file of integers separated by whitespace. This method will take the next integer and add it to my linked list.
public void readValues() {
LinkedList list = new LinkedList();
while(scan.hasNextInt()) {
Integer someData = scan.nextInt();
list.addNode(someData);
}
list.printList();
}
This method is in my LinkedList class which takes the data sent from my readValues method in my files class.
public void addNode(Integer someData) {
myNode = new LinkedNode(someData,null);
//initialize node if this is first element
if (head == null) {
head = myNode;
size++;
}
else if (myNode.getNext() == null) {
myNode.setNext(myNode);
size ++;
}
else if (myNode.getNext() != null) {
while(myNode.getNext() != null) {
myNode = myNode.getNext();
}
myNode.setNext(myNode);
size++;
}
}
This method is also in my LinkedList class and successfully prints the head of my list which with my data is the number 40 followed by ---> and then nothing else. It should print ever other integer read in from my file.
public void printList() {
LinkedNode current = head;
if (head == null) {
System.out.print("list is empty");
return;
}
while(current != null) {
System.out.print(current.getElement());
System.out.print(" --> ");
current = current.getNext();
}
}
LinkedNode class:
public class LinkedNode {
Integer data;
LinkedNode next;
public LinkedNode(Integer someData, LinkedNode next) {
this.data = someData;
this.next = null;
}
public int getElement() {
return data;
}
public void setElement(Integer data) {
this.data = data;
}
public LinkedNode getNext() {
return next;
}
public void setNext(LinkedNode next) {
this.next = next;
}
public String toString() {
return data + "";
}
}
Your code has a small bug in the if else conditions in your addNode() method due to which your data is not getting added in the list.
Root Cause
When you add a new node to your list,
In the first iteration
The head is currently null and hence the first if conditions becomes true and your first node gets added (That's why you got the data 40).
In the Subsequent iteration(s)
your else if condition checks the myNode's next pointer which will always be null (as per the constructor) and thus it's next pointer points towards itself. The nodes created from here do not become the part of the list as the next pointer of head was never assigned to any of these and these nodes also point to themselves only.
Solution
I made a little modification in the if else conditions:
public void addNode(Integer someData) {
LinkedNode myNode = new LinkedNode(someData,null);
//initialize node if this is first element
if (head == null) {
head = myNode;
size++;
}
else if (head.getNext() == null) {
head.setNext(myNode);
size ++;
}
else if (head.getNext() != null) {
System.out.println("in second else if");
LinkedNode n = head;
while(n.getNext() != null) {
n = n.getNext();
}
n.setNext(myNode);
size++;
}
}
PS: Try debugging your code with dry run, it's a great mental exercise and helps in boosting the learning curve significantly too. All the best! :)
The problem is with your addNode() method. Inside the addNode() method you are first creating a new node named mynode. Now when the head is null it sets head to mynode, thats ok. But when the head is not null the mynode is not being added to the list. Thats why only the first element exist and other's are getting lost.
Hope this helps. Let me know if I can help with anything else. Happy coding!
I am a beginner in java .I am implementing recursion in linked lists to print the elements in reverse order but i think that there is a semantic error in my code , check my code(especially that reverse method) thanks in an advance.
output:78 30 52 send after which item count from head u need to insert
package practice;
public class Linkedlist {
Node head;
public Linkedlist() {
head = null;
}
public void insert(int data) {
Node obj1 = new Node(data);
obj1.next = head;
head = obj1;
}
public void append(int data) {
Node newn = new Node(data);
if (head == null) {
newn.next = null;
head = newn;
return;
}
Node n = head;
while (n.next != null) {
n = n.next;
}
newn.next = null;
n.next = newn;
}
void delete(int data) {
if (head == null) {
return;
} else if (head.data == data) {
head = head.next;
return;
}
Node curr = head;
while (curr.next != null) {
if (curr.next.data == data) {
curr.next = curr.next.next;
}
curr = curr.next;
}
}
void insertAt(int count, int data) {
Node h = head;
if (count == 0) {
this.insert(data);
return;
}
while (h.next != null) {
if (count == 0) {
Node f = new Node(data);
f = h.next;
h = f;
return;
}
count--;
h = h.next;
}
}
public void reverse() {
if (head == null) {
System.out.println("null");
} else {
this.reverseRecursive(head);
}
}
private void reverseRecursive(Node nod) {
if (nod == null) {
return;
}
reverseRecursive(nod.next);
System.out.print(nod.data + " ");
}
class Node {
Node next;
int data;
public Node(int data) {
this.data = data;
}
}
public static void main(String args[]) {
Linkedlist obj = new Linkedlist();
obj.insert(78);
obj.insert(30);
obj.insert(52);
obj.reverse();
System.out.println("send after which item count from head u need to insert");
obj.insertAt(2, 5);
}
}
Looking at your code, I don't think there is anything wrong with your Reverse method. It is actually printing in reverse order. What's throwing you off is probably the way you are inserting the elements. Your insert() method is actually a stack. ( It inserts at top ). So after all insertions, head points to 52 and not 78. So when you print, the reverse list is printed as :
78 30 52
Also, your code needs a bit of formatting and should follow java conventions. Method names start with lower case and class names with uppercase. Good luck :)
In your LinkedList instead of using the insert method, which add an element at the head use the method append which adds the element at the end of the LinkedList and then call the reverse method.
Here is my Node class:
private class Node {
private int key; // the key field
private Object data; // the rest of the data item
private Node left; // reference to the left child/subtree
private Node right; // reference to the right child/subtree
private Node parent; // reference to the parent
.. and so on.
This is the inorder iterator with next() and hasNext() methods:
private class inorderIterator implements LinkedTreeIterator {
private Node nextNode;
private inorderIterator() {
// The traversal starts with the root node.
nextNode = root;
if(nextNode == null)
return;
while (nextNode.left != null)
nextNode = nextNode.left;
}
public boolean hasNext() {
return (nextNode != null);
}
public int next() {
if(!hasNext())
throw new NoSuchElementException();
Node r = nextNode;
if (nextNode.right != null) {
nextNode = nextNode.right;
while (nextNode.left != null) {
nextNode = nextNode.left;
}
return r.key;
} else while (true) {
if (nextNode.parent == null) {
nextNode = null;
return r.key;
}
if (nextNode.parent.left == nextNode) {
nextNode = nextNode.parent;
return r.key;
}
nextNode = nextNode.parent;
}
return r.key;
}
}
The problem is, it only ever prints the left nodes on the left sub-tree.
For example, for a tree with root node 17, left node 15 and right node 19, it only prints 15.
So it never enters a right subtree.
I'm guessing the problem is with the else while (true) portion, but I can't figure out how to fix this.
You could try a recursive approach.
Something like:
public void printTreeInOrder(Node node){
if(node.left != null){
printTree(node.left);
}
System.out.println(node.key);
if(node.right != null){
printTree(node.right);
}
}
If you passed this method the root node it should print out the entire tree for you.
I hope this helps.
Best.
Turns out that the parent field of my nodes was not being updated properly. Once that was fixed, the iterator worked properly.
I would use a stack with this helper method:
Node advance_to_min(Node r)
{
while (r.left != null)
{
s.push(r);
r = r.left;
}
return r;
}
The first node inorder is given by the call to this method on the root. Something like:
curr = advance_to_min(curr);
And then I would implement next() thus:
void next()
{
curr = curr.right;
if (curr != null)
{
curr = advance_to_min(curr);
return;
}
if (s.is_empty())
curr = null;
else
curr = s.pop();
}
curr and the stack s would be iterator attributes. curr would point to the current node in the inorder sequence.
The cost O(lg n) at worst case for each next() call (if the tree tends to be balanced) and the approach does not require parent pointers; so, it would have the same space cost than using parent pointers but only in the worst case
I was trying to reverse a linked list using recursion. I got the solution, but can't get it to work for below question found on internet.
Reverse a linked list using recursion but function should have void
return type.
I was able to implement the function with return type as Node. Below is my solution.
public static Node recursive(Node start) {
// exit condition
if(start == null || start.next == null)
return start;
Node remainingNode = recursive(start.next);
Node current = remainingNode;
while(current.next != null)
current = current.next;
current.next = start;
start.next = null;
return remainingNode;
}
I cannot imagine if there will be such a solution to this problem.
Any suggestions ?
Tested, it works (assuming you have your own implementation of a linked list with Nodes that know the next node).
public static void reverse(Node previous, Node current) {
//if there is next node...
if (current.next != null) {
//...go forth and pwn
reverse(current, current.next);
}
if (previous == null) {
// this was the start node
current.next= null;
} else {
//reverse
current.next= previous;
}
}
You call it with
reverse(null, startNode);
public void recursiveDisplay(Link current){
if(current== null)
return ;
recursiveDisplay(current.next);
current.display();
}
static StringBuilder reverseStr = new StringBuilder();
public static void main(String args[]) {
String str = "9876543210";
reverse(str, str.length() - 1);
}
public static void reverse(String str, int index) {
if (index < 0) {
System.out.println(reverseStr.toString());
} else {
reverseStr.append(str.charAt(index));
reverse(str, index - 1);
index--;
}
}
This should work
static void reverse(List list, int p) {
if (p == list.size() / 2) {
return;
}
Object o1 = list.get(p);
Object o2 = list.get(list.size() - p - 1);
list.set(p, o2);
list.set(list.size() - p - 1, o1);
reverse(list, p + 1);
}
though to be efficient with LinkedList it should be refactored to use ListIterator
I am not familiar with Java, but here is a C++ version. After reversing the list, the head of list is still preserved, which means that the list can still be accessible from the old list head List* h.
void reverse(List* h) {
if (!h || !h->next) {
return;
}
if (!h->next->next) {
swap(h->value, h->next->value);
return;
}
auto next_of_next = h->next->next;
auto new_head = h->next;
reverse(h->next);
swap(h->value, new_head->value);
next_of_next->next = new_head;
h->next = new_head->next;
new_head->next = nullptr;
}
Try this code instead - it actually works
public static ListElement reverseListConstantStorage(ListElement head) {
return reverse(null,head);
}
private static ListElement reverse(ListElement previous, ListElement current) {
ListElement newHead = null;
if (current.getNext() != null) {
newHead = reverse(current, current.getNext());
} else {//end of the list
newHead=current;
newHead.setNext(previous);
}
current.setNext(previous);
return newHead;
}
public static Node recurse2(Node node){
Node head =null;
if(node.next == null) return node;
Node previous=node, current = node.next;
head = recurse2(node.next);
current.next = previous;
previous.next = null;
return head;
}
While calling the function assign the return value as below:
list.head=recurse2(list.head);
The function below is based on the chosen answer from darijan, all I did is adding 2 lines of code so that it'd fit in the code you guys want to work:
public void reverse(Node previous, Node current) {
//if there is next node...
if (current.next != null) {
//...go forth and pwn
reverse(current, current.next);
}
else this.head = current;/*end of the list <-- This line alone would be the fix
since you will now have the former tail of the Linked List set as the new head*/
if (previous == null) {
// this was the start node
current.next= null;
this.tail = current; /*No need for that one if you're not using a Node in
your class to represent the last Node in the given list*/
} else {
//reverse
current.next= previous;
}
}
Also, I've changed it to a non static function so then the way to use it would be: myLinkedList.reverse(null, myLinkedList.head);
Here is my version - void ReverseWithRecursion(Node currentNode)
- It is method of LinkListDemo Class so head is accessible
Base Case - If Node is null, then do nothing and return.
If Node->Next is null, "Make it head" and return.
Other Case - Reverse the Next of currentNode.
public void ReverseWithRecursion(Node currentNode){
if(currentNode == null) return;
if(currentNode.next == null) {head = currentNode; return;}
Node first = currentNode;
Node rest = currentNode.next;
RevereseWithRecursion(rest);
first.next.next = first;
first.next = null;
}
You Call it like this -
LinkListDemo ll = new LinkListDemo(); // assueme class is available
ll.insert(1); // Assume method is available
ll.insert(2);
ll.insert(3);
ll.ReverseWithRecursion(ll.head);
Given that you have a Node class as below:
public class Node
{
public int data;
public Node next;
public Node(int d) //constructor.
{
data = d;
next = null;
}
}
And a linkedList class where you have declared a head node, so that it can be accessed by the methods that you create inside LinkedList class. The method 'ReverseLinkedList' takes a Node as an argument and reverses the ll.
You may do a dry run of the code by considering 1->2 as the linkedList. Where node = 1, node.next = 2.
public class LinkedList
{
public Node? head; //head of list
public LinkedList()
{
head = null;
}
public void ReverseLinkedList(Node node)
{
if(node==null)
{
return;
}
if(node.next==null)
{
head = node;
return;
}
ReverseLinkedList(node.next); // node.next = rest of the linkedList
node.next.next = node; // consider node as the first part of linkedList
node.next = null;
}
}
The simplest method that I can think of it's:
public static <T> void reverse( LinkedList<T> list )
{
if (list.size() <= 1) {
return;
}
T first = list.removeFirst();
reverse( list);
list.addLast( first );
}
I want to remove duplicates from sorted linked list {0 1 2 2 3 3 4 5}.
`
public Node removeDuplicates(Node header)
{
Node tempHeader = null;
if(header != null)
tempHeader = header.next;
else return header;
Node prev = header;
if((tempHeader == null)) return header ;
while(tempHeader != null)
{
if(tempHeader.data != prev.data)
{
prev.setNext(tempHeader);
}
tempHeader = tempHeader.next;
}
prev = header;
printList(prev);
return tempHeader;
}
`
prev.setNext(tempHeader) is not working correctly inside the while loop. Ideally when prev = 2 and tempHeader = 3, prev.next should be node with data = 3.
Printlist function just takes header pointer and prints the list.
Node definition is given below.
public class Node
{
int data;
Node next;
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
The loop is sorted, so you know that duplicates are going to sit next to each other. If you want to edit the list in place then, you've got to have two list pointers (which you do). The one you call tempHeader and prev, and you've got to advance them both in the the list as you go (which I don't see in the code). Otherwise, if you don't advance the prev pointer as you go, then you're always comparing the element under tempHeader to the first item in the list, which is not correct.
An easier way to do this, however, is to build a new list as you go. Simply remember the value of the last item that you appended to the list. Then if the one that you're about to insert is the same then simply don't insert it, and when you're done, just return your new list.
I can give you 2 suggestions for the above suggestion
1) Convert the linked List to Set, that will eliminate the duplicates and
Back from Set to the Linked list
Code to get this done would be
linkedList = new LinkedList<anything>(new HashSet<anything>(origList));
2) You can use LinkedHashSet, if you dont want any duplicates
In this case no return value is needed.
public void removeDuplicates(Node list) {
while (list != null) {
// Walk to next unequal node:
Node current = list.next;
while (current != null && current.data.equals(list.data)) {
current = current.next;
}
// Skip the equal nodes:
list.next = current;
// Take the next unequal node:
list = current;
}
}
public ListNode removeDuplicateElements(ListNode head) {
if (head == null || head.next == null) {
return null;
}
if (head.data.equals(head.next.data)) {
ListNode next_next = head.next.next;
head.next = null;
head.next = next_next;
removeDuplicateElements(head);
} else {
removeDuplicateElements(head.next);
}
return head;
}
By DoublyLinked List and using HashSet,
public static void deleteDups(Node n) {
HashSet<Integer> set = new HashSet<Integer>();
Node previous = null;
while (n != null) {
if (set.contains(n.data)) {
previous.next = n.next;
} else {
set.add(n.data);
previous = n;
}
n = n.next;
}
}
doublylinkedList
class Node{
public Node next;
public Node prev;
public Node last;
public int data;
public Node (int d, Node n, Node p) {
data = d;
setNext(n);
setPrevious(p);
}
public Node() { }
public void setNext(Node n) {
next = n;
if (this == last) {
last = n;
}
if (n != null && n.prev != this) {
n.setPrevious(this);
}
}
public void setPrevious(Node p) {
prev = p;
if (p != null && p.next != this) {
p.setNext(this);
}
}}