I am trying to implement linked list and I dont get whats wrong with this code.
Goes into an infinite loop printing 1...the start node is instantiated the first time when insert() is invoked
Node
public class Node {
int data;
Node next;
public Node(int data, Node next) {
super();
this.data = data;
this.next = next;
}
public Node()
{
super();
}
}
LinkedList
public class LinkedList {
Node start = null;
void insert(int value)
{
Node current;
current = start;
if(start == null)
{
start = new Node(value, null);
start.data = value;
start.next = null;
}
else
{
while(current.next != null)
{
current = current.next;
}
current.next = new Node();
current.next.data = value;
current.next.next = null;
}
}
void show()
{
Node curr = start;
while(curr.next != null)
{
System.out.println(curr.data);
}
}
public static void main(String[] args) {
LinkedList ll = new LinkedList();
ll.insert(1);
ll.insert(7);
ll.insert(5);
ll.insert(3);
ll.insert(9);
ll.show();
}
}
Change you show() method like below:
void show() {
Node curr = start;
while (curr.next != null) {
System.out.println(curr.data);
curr = curr.next; // This part was missing.
}
}
In your show() method you are missing the:
curr = curr.next
after you are printing the current node's value;
use curr = curr.next; in the while loop of
Related
I was working on a program to add nodes to a list, but I seem to be doing something wrong...
My java program has three Classes; Demo, Lista and Node
Class Node:
public class Node {
private int num;
private Node tail;
private Node head;
public Node (int num, Node head, Node tail) {
this.num = num;
this.head = head;
this.tail = tail;
}
}
Class Lista:
public class Lista {
private Node nil;
public Lista () {
nil = null;
}
public void add (int num) {
Node newNode = new Node(num, head, tail);
if (head == null) {
head = newNode;
tail = newNode;
}
}
public void display () {
Node current = head;
while(current != null) {
System.out.print(current.num);
}
}
}
Class Demo:
public class Demo {
public static void main ( String [] args) {
Lista lista = new Lista();
lista.add(3);
lista.add(9);
lista.add(7);
lista.display();
}
}
Demo class is to add the different nodes to the list "lista". Class Node has num, head which is the next one and tail which is the previous one. How can I go about getting Class Lista to be able to use head and tail from Class Node? And if it is possible would this code work when running Demo? What should I change/modify to get this to work?
You may want to modify your code something like this:
EDIT - This is a doubly-linked list implementation.
class Node {
int num;
Node prev;
Node next;
Node(int num) {
this.num = num;
}
Node(int num, Node prev, Node next) {
this.num = num;
this.prev = prev;
this.next = next;
}
void setPrev(Node prev) {
this.prev = prev;
}
void setNext(Node next) {
this.next = next;
}
}
class Lista {
Node root;
Node endNode;
public void add(int num) {
Node n = new Node(num);
if (root == null) {
root = n;
} else {
n.setPrev(endNode);
endNode.setNext(n);
}
endNode = n;
}
public void display() {
Node iterateeNode = root;
while (iterateeNode != null) {
System.out.print(iterateeNode.num + " ");
iterateeNode = iterateeNode.next;
}
}
}
The selected answer is technically not correct. For a (single) Linked List, all your Lista need is a single (head) node. Additionally, the Node class needs a single (next) Node field.
The following is a potential implementation of Node:
public class Node {
private Node next;
private int value;
public Node(int value) {
this.value = value;
}
public boolean hasNext() {
return next != null;
}
public Node next() {
return next;
}
public void add(Node node) {
if (next == null) {
next = node;
} else {
Node temp = next;
while (temp != null) {
temp = temp.next;
}
temp = node;
}
}
#Override
public String toString() {
return String.valueOf(value);
}
}
The add() method will insert the new node in next if it is null. Otherwise, it will traverse the nodes until it finds the tail node (the one where next is null).
The Lista has only the first element in the list (head node).
public class Lista {
private Node head;
public void add(Node node) {
if (head == null) {
head = node;
} else {
Node temp = head;
while (temp.hasNext()) {
temp = temp.next();
}
temp.add(node);
}
}
// Other methods
}
When the add() function in the list is called, it will either add the new node as the head (if the list doesn't have one already) or rely on the already added nodes to figure out where the end of the list is in order to insert the new node.
Lastly, to display the list, just override the toString() method in node and add the "toString" value to a string buffer and send the concatenated string value to the console similar to the the code below.
public void display() {
StringBuilder buff = new StringBuilder("[");
buff.append(head);
if (head != null) {
Node next = head.next();
buff.append(",");
while (next != null) {
buff.append(next);
next = next.next();
buff.append(",");
}
}
buff.append("]");
int idx = buff.lastIndexOf(",");
buff.replace(idx, idx+1, "");
System.out.println(buff.toString());
}
Executing the following displays [3,9,7] as expected.
public class Demo {
public static void main ( String [] args) {
Lista lista = new Lista();
lista.add(new Node(3));
lista.add(new Node(9));
lista.add(new Node(7));
lista.display();
}
}
I would like to ask: how to add a new node before the head of a linked list:
Here is my code:
// Definition for singly-linked list.
public class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
public void addAfter(ListNode thisnode, int x) {
ListNode newNode = new ListNode(x);
if(thisnode == null) {
//add before the head
newNode.next = this;
}//wrong here
else {
ListNode currentNext = thisnode.next;
thisnode.next = newNode;
newNode.next = currentNext;
}
return;
}//done addAfter this node
}
For example, with the input list 2 100 300 800, l.addAfter(null,500); the output should be
500 2 100 300 800 but my output is still 2 100 300 800. Thank you.
Inserting before head would change the value of head. Which you can't do from inside the method.
public ListNode addAfter(ListNode thisnode, int x) {
ListNode newNode = new ListNode(x);
if(thisnode == null) {
//add before the head
newNode.next = this;
return newNode;
} else {
ListNode currentNext = thisnode.next;
thisnode.next = newNode;
newNode.next = currentNext;
}
return this;
}
And the caller would call it like l = l.addAfter(null,500);
First of all, make your code clear, readable and consistent. Here is what you asked for:
public class Node {
private int value;
private Node next;
public Node(int value) {
this.value = value;
next = null;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
public class ListNode {
private Node head;
public ListNode(Node head) {
this.head = head;
}
public Node getHead(){
return head;
}
// Here is your function
public void insertBeforeHead(int value) {
Node node = new Node(value);
node.setNext(head);
head = node;
}
}
// Node Class
public class SinglyListNode {
int val;
SinglyListNode next;
SinglyListNode(int x) { val = x; }
}
//Singly Linked List class
public class SinglyLinkedList {
private SinglyListNode head;
public SinglyLinkedList() {
head = null;
}
// add at beginning
public void addAtBeginning(int value){
SinglyListNode node = new SinglyListNode(value);
if (head != null) {
node.next = head;
}
head = node;
}
// print list
public void printList(){
System.out.println("printing linked list");
SinglyListNode curr = head;
while (curr != null){
System.out.println(curr.val);
curr = curr.next;
}
}
}
//main method
public static void main(String[] args) {
SinglyLinkedList linkedList = new SinglyLinkedList();
linkedList.addAtBeginning(5);
linkedList.addAtBeginning(6);
linkedList.addAtBeginning(7);
linkedList.printList();
}
You can always make one head that is constant and add all the new elements after it.
Example:
Head - Link1 - Link2 - Link3
Whenever you want to add newLink you can just add it in this manner.
Head - newLink - Link1 - Link2 - Link3
In this way you head information is never lost and it reduce the chances of losing your entire list.
You can explore my codebase here which implements it.
https://github.com/SayefReyadh/tutorials/tree/master/LinkedList-Bangla-Tutorial/LinkedListExample/src/linkedlistexample
The method is implemented as insertFront in LinkedList.java
I have been debugging this for hours and I cannot see any reason why my search method cannot find anything. and my toString only ever returns the first node, then again, nothing. can someone help me?
While debugging, I can confirm that the order of the list is correct, I can switch around the addLast and addFirst and will always return what should be the first element, but otherwise, I do not know. the first is always sored in head.info and during debugging I see that but then the prev and next are still null.
thanks in advance!
public class DoubleLinkedList {
private DoubleNode head;
public DoubleLinkedList() {
head = null;
}
public class DoubleNode {
int info;
DoubleNode prev;
DoubleNode next;
public DoubleNode(int key) {
info = key;
prev = next = null;
}
}
public DoubleNode search(int key) {
DoubleNode current = this.head;
while (current != null && current.info != key) {
current = current.next;
}
return current;
}
public void addFirst(int key) {
this.head = new DoubleNode(key);
}
public void addLast(int key) {
DoubleNode node = new DoubleNode(key);
DoubleNode current;
if (head == null) {
this.head = node;
} else {
current = this.head;
while (current.next != null) {
current = current.next;
current.next = node;
node.prev = current;
}
}
}
public int delete(int key) {
DoubleNode current, sent;
current = search( key );
if (current != null) {
sent = delete( current );
return sent.info;
} else {
return -1;
}
}
private DoubleNode delete(DoubleNode node) {
if (node.prev != null) {
(node.prev).next = node.next;
} else {
this.head = node.next;
}
if (node.next != null) {
(node.next).prev = node.prev;
}
return node;
}
public String toString() {
String string = "";
while (head != null) {
string += head.info + " ";
head = head.next;
}
return string;
}
public static void main(String[] args) {
DoubleLinkedList test = new DoubleLinkedList();
test.addLast( 3 );
test.addLast( 5 );
test.addFirst( 7 );
System.out.println(test);
System.out.println( "Search: " + test.search( 1 ) );
}
}
The results come out as:
7,
Search: null
Your addFirst method isn't currently setting the new head's next property. It needs to be something more like this:
public void addFirst(int key) {
DoubleNode node = new DoubleNode(key);
node.next = this.head;
this.head = node;
}
Take a look at this example:
public class Test {
public static void main(String[] args) {
List list = new List();
list.addNode("1");
list.addNode("2");
list.addNode("3");
System.out.println(list);// not implemented
}
}
class List {
Node head;
Node tail;
class Node {
Node next;
Node previous;
String info;
public Node(String info) {
this.info = info;
}
}
void addNode(String info) {
Node node = new Node(info);
if (head == null) {
head = tail = node;
} else if(tail == head){
Node next = new Node(info);
tail.next = next;
head = next;
head.previous = tail;
} else{
Node next = new Node(info);
Node current = head;
head.next =next;
head = next;
head.previous = current;
}
}
}
I'm trying to write a method called copyAlternate which copy alternate elements from a single linked list and put them in another Single linked list sent as a parameter in the method
for example: if the first Single Linked List is( 4,6,10,12,2)
the method should generate a single linked list with (4,10,2)
here is my code:
public boolean copyAlternate(SingleLinkedList<E> list1)
{
if(head==null)
return false;
Node <E> temp = head;
ArrayList <E> a1 = new ArrayList<E>();
while(temp!=null) {
a1.add(temp.data);
temp=temp.next;
}
Node<E> tmp1=list1.head;
for(int i=0;i<a1.size();i=i+2){
if(list1.head==null) {
list1.head =new Node(a1.get(i));
tmp1=head;
size++;
}
else
{
tmp1.next=new Node(a1.get(i));
size++;
tmp1=tmp1.next;
}
}
return true;
}
I got only 4 from method not (4,10,2)
so what is the problem with my code?
Here is a full example if you need it, try not to copy it entirely but study it and understand what it's doing:
public class Main {
public static void main(String[] args) {
SingleLinkedList<Integer> list = new SingleLinkedList<>();
// (4, 6, 10, 12, 2)
list.add(4).add(6).add(10).add(12).add(2);
SingleLinkedList<Integer> newList = copyAlternate(list);
System.out.println(newList);
// prints: (14, 10, 2)
}
public static class Node<T> {
public Node<T> next;
public T data;
public Node() {}
public Node(T data) {this.data = data;}
}
public static class SingleLinkedList<T> {
private Node<T> head;
private Node<T> tail;
public SingleLinkedList<T> add(T data) {
if (tail != null) {
tail.next = new Node<>(data);
tail = tail.next;
} else {
head = new Node<>(data);
tail = head;
}
return this;
}
#Override public String toString() {
StringBuilder sb = new StringBuilder();
if (head != null) {
sb.append(head.data);
Node<T> curr = head.next;
while (curr != null) {
sb.append(", ").append(curr.data);
curr = curr.next;
}
}
return sb.toString();
}
}
/**
* Copies only the even index nodes (0, 2, 4..) into a new list and returns that list.
* Doesn't create a deep copy of data
*/
public static <T> SingleLinkedList<T> copyAlternate(SingleLinkedList<T> list) {
Objects.requireNonNull(list, "list");
SingleLinkedList<T> newList = new SingleLinkedList<>();
Node<T> other = list.head;
if (other != null) {
// copy other data to head of new list and remember that as the current node
Node<T> curr = newList.head = new Node<>(other.data);
// get the next next other node
other = other.next;
if (other != null) {
other = other.next;
}
while (other != null) {
// copy the data into the next node then remember that as the current node
curr = curr.next = new Node<>(other.data);
// get the next next other node
other = other.next;
if (other != null) {
other = other.next;
}
}
}
return newList;
}
}
Another way you can achieve it. Hope it will help.
// define the structure of a single node
class ListNode<T>
{
public T data;
public ListNode<T> next;
public ListNode(T data)
{
this.data = data;
this.next = null;
}
}
public class SingleLinkedListGenerics<T>
{
private ListNode<T> head = null;
private ListNode<T> tail = null;
// used to insert a node at the end of linked list
public void insertLast(T data)
{
ListNode<T> newNode = new ListNode<>(data);
if (head == null)
{
head = tail = newNode;
}
else
{
tail.next = newNode;
tail = newNode;
}
}
// For printing Linked List
public void displayList()
{
System.out.println("\nPrinting LinkedList (head --> last) ");
ListNode<T> current = head;
while (current != null)
{
System.out.println(current.data + ", ");
current = current.next;
}
}
public static <T> SingleLinkedListGenerics<T> copyAlternate(SingleLinkedListGenerics<T> list)
{
if (list.head == null)
return null;
SingleLinkedListGenerics<T> newList = new SingleLinkedListGenerics<>();
ListNode<T> tmp = list.head;
ListNode<T> newNode = new ListNode<>(tmp.data); // getting the first node
newList.head = newNode;
newList.tail = newNode;
tmp = tmp.next;
while (tmp != null && tmp.next != null) //
{
tmp = tmp.next; // skipping one node
newList.insertLast(tmp.data);
tmp = tmp.next;
}
return newList;
}
public static void main(String args[])
{
SingleLinkedListGenerics<Integer> myLinkedlist = new SingleLinkedListGenerics<>();
myLinkedlist.insertLast(4);
myLinkedlist.insertLast(6);
myLinkedlist.insertLast(10);
myLinkedlist.insertLast(12);
myLinkedlist.insertLast(2);
myLinkedlist.displayList();
SingleLinkedListGenerics<Integer> myLinkedlist1 = copyAlternate(myLinkedlist);
myLinkedlist1.displayList();
}
}
I'm really struggling to fix my code for this. I've created a Doubly Linked list that I am trying to traverse in reverse.
Any ideas?
Here's my code: Node.java:
public class Node {
String data;
Node next;
public Node(String data) {
super();
this.data = data;
this.next = null;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public Node getNext() {
if (this.next != null)
return this.next;
else
return null;
}
public void setNext(Node a) {
this.next = a;
}
#Override
public String toString() { //CHECK
if(data== null){
return "null";
}
else
return data + "-->";
}
}
Here's the second class "DNode.java":
public class DNode extends Node {
Node prev;
public DNode(String data) {
super(data);
this.prev = null;
}
public Node getPrev() {
return prev;
}
public void setPrev(Node prev) {
this.prev = prev;
}
}
Lastly, here is DoublyLinkedList.java: (Overrides "add" and "remove" methods from another class "Linked List")
public class DoublyLinkedList extends LinkedList {
DNode head, tail,current;
public DoublyLinkedList() {
this.head = this.tail = this.current = null;
}
public void add(DNode a) { //CHECK
if (this.head == null) {
this.head = tail = current= a;
this.head.prev = null;
}
else{
//a.setPrev(this.current);
this.current.next= a;
a.setPrev(this.current);
this.current = this.tail = a;
}
}
#Override
public void remove(String removestring) {
this.current = head;
this.current.prev = head;
while (this.current.getData() != removestring) {
if (this.current.next == null) {
System.out.println("not found");
return;
} else {
this.current.prev = this.current;
this.current = (DNode) current.next;
}
}
if (this.current == head) {
head = (DNode) head.next;
} else {
this.current.prev.next = (DNode) this.current.next;
}
}
public void printList() {
DNode temp = this.head;
while (temp != null) {
System.out.println(temp);
temp = (DNode) temp.getNext();
}
}
public void reverseList(){
this.current = this.tail;
this.current.setNext(this.current.getPrev());
this.current.setPrev(null);
this.current = (DNode) this.current.getNext();
while(this.current.getPrev()!= null){
if(this.current.getNext() == null){
this.current.setNext((this.current).getPrev());
this.current.setPrev(null);
this.current = (DNode)this.current.getNext();
}
else{
DNode tempprev = (DNode) this.current.getNext();
this.current.setNext(this.current.getPrev());
this.current.setPrev(tempprev);
this.current = (DNode) this.current.getNext();
}
DNode temp2 = this.tail;
this.head = this.tail;
this.tail = temp2;
}
}
I'm able to print the list going forwards, but going backwards I am running into an infinite loop. Any ideas?
Thanks!
Well, we already have a method to go forwards. Because this is doubly linked, we can just convert this code line by line and instead of moving next (forwards) we move previous (backwards). We also start at the tail instead of the head.
Whereas this was your old method for printing forwards:
public void printList() {
DNode temp = this.head;
while (temp != null) {
System.out.println(temp);
temp = (DNode) temp.getNext();
}
}
This could be your new method for printing backwards:
public void printBackwardsList() {
DNode temp = this.tail;
while(temp != null) {
System.out.println(temp);
temp = (DNode) temp.getPrev();
}
}
Notice how they are almost exactly the same, except we swapped out tail for head and getNext for getPrev.
Your class model seems overly complex. You don't need a DNode class at all to do this. Your method to print the list in reverse should be as simple as the method to print the list normally
public void printListReverse() {
Node temp = this.tail;
while (temp != null) {
System.out.println(temp);
temp = temp.getPrevious();
}
}
assuming you build and maintain the list properly.
while(this.current.getPrev()!= null)
replace with
while(this.current.getPrev()!= head)