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?
Related
Try to create an empty link list. To creating the empty list I create a inner class Node and made it static such that main class can access it.
import java.util.LinkedList;
public class Addtwo {
static class Node {
int data;
Node next;
Node head;
Node(int d) {
data = d;
next = null;
// Constructor
}
public static void main (String args[])
{
/* Start with the empty list. */
LinkedList llist = new LinkedList();
llist.head = new Node(1);
Node second = new Node(2);
Node third = new Node(3);
llist.head.next = second;
second.next = third;
}
}
}
It cannot find the node head that I create within the inner class Node. How to solve this?
Error:
Error :(22, 22) java: cannot find symbol
symbol : variable head
location: variable llist of type java.util.LinkedList
First, if you want to use the JDK's LinkedList, you don't need to manage the nodes of the list, this work is already implemented. You only need to do this:
LinkedList<Integer> llist = new LinkedList<Integer>();
llist.add(1);
llist.add(2);
llist.add(3);
And there is more functionality here.
Second, if you want to implement your own linked list (I think this is what you want), you donĀ“t need to use the JDK's LinkedList, you can start with this basic code:
public class Addtwo {
static class Node {
int data;
Node next;
Node(int d) {
data = d;
next = null;
}
public static void main(String args[]) {
/* Start with the empty list. */
Node head = new Node(1);
Node second = new Node(2);
Node third = new Node(3);
head.next = second;
second.next = third;
Node iterator = head;
while (iterator != null) {
System.out.println(iterator.data);
iterator = iterator.next;
}
}
}
}
PS: You don't need to store a head for each node. You probably need another class LinkedListManager to implement some methods and store the head and the tail of the list.
Here's what I have:
public class Node{
Object data;
Node next;
Node(Object data, Node next){
this.data = data;
this.next = next;
}
public Object getData(){
return data;
}
public void setData (Object data){
this.data = data;
}
public Node getNext(){
return next;
}
public void setNext(Node next){
this.next = next;
}
}
How do I write the code to add a Node at the end of a list?
So if I had
head -> [1] -> [2] -> null
How do I get to
head -> [1] -> [2] -> [3] -> null
Actually...I'm not even sure if I have to add to the end. I think it's valid to add and then sort? Not sure.
Thanks!
public void addToEnd(Object data){
Node temp = this;
while(temp.next!=null)temp=temp.next;
temp.next=new Node(data, null);
}
It's a linked list. You either have to
A) iterate through all your nodes starting at the head, find the last node, then add one.
or
B) keep track of the tail, add to the tail, then update tail to the new last node.
Start from the head:
Node currentNode = headNode;
while (node.getNext() != null) {
currentNode = currentNode.getNext();
}
currentNode.setNext(newNodeForInsertion);
A faster way is to store the last node of the list somewhere so you don't have to go through the whole list.
Recursively navigate through each node until you hit the end.
public void navigate(Node insertNode)
{
if(next == null)
next = insertNode;
else
next.navigate(insertNode);
}
To add to the end, you'd have to walk to the end of the list (i.e., to where next=null) and add a new node there.
In the real world, you'd use an ArrayList for this and not bother with a linked list or manual structure at all.
In your method to add a node, write a while loop that starts at the head and looks to see if the "next node" is null. If it is not, advance to the "next node" and repeat.
Once you are at the node that points to nothing, adding the node is as simple as reassigning the null reference to the node to be added.
A recursive solution:
public void addToEnd(Object data){
if (next==null)
next = new Node(data, null);
else
next.addToEnd(data);
}
Node n = head;
while(n.getNext() != null){
n = n.getNext();
}
n.setNext(nodeToAdd);
That's not sorted, which I can't tell from your question if you want it sorted. Which opens up another whole can of worms such as what do you want to sort on, if you have a linked list of type Object there isn't really anything meaningful to sort on.
I have been trying to implement a singly linked list in java with generics and I tried to implement a method "headInsert()" to insert a new Node and make it the new head of the list.
I am trying to achieve this by creating a new Node and swapping it with the head.
However, I have an error while I am trying to parameterize the new Node.
Here is the code I have written and I would appreciate any sort of help I could get.
Thank you in advance.
package datastructures;
public class LinkedList<E> {
private Node head;
private Node tail;
private static class Node<E> {
E data;
Node next;
Node (E data) {
this.data = data;
}
}
//Insert at the beginning of a LinkedList
public void headInsert(Node n) {
if(head == null) {
head = n;
}
else {
Node temp = head;
Node n1 = new Node(n1.data); //error here
n1.next=head;
head=n1;
}
}
The error occurs because n1 was not created yet when you try to access n1.data, it should be:
Node n1 = new Node(n.data);
That said, you don't really need to create a new node to place in the head. You can implement headInsert() like this:
public void headInsert(Node n) {
n.next = this.head;
this.head = n;
}
Suppose you have an empty list (head is null) and you want to add node A, A.next will point to null, and head will point to A resulting in the list A->null
Now suppose you have a non-empty list, like A->B->C, and you want to insert node Z, Z.next will point to A, and head will point to Z so you will get Z->A->B->C.
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
Here's what I have:
public class Node{
Object data;
Node next;
Node(Object data, Node next){
this.data = data;
this.next = next;
}
public Object getData(){
return data;
}
public void setData (Object data){
this.data = data;
}
public Node getNext(){
return next;
}
public void setNext(Node next){
this.next = next;
}
}
How do I write the code to add a Node at the end of a list?
So if I had
head -> [1] -> [2] -> null
How do I get to
head -> [1] -> [2] -> [3] -> null
Actually...I'm not even sure if I have to add to the end. I think it's valid to add and then sort? Not sure.
Thanks!
public void addToEnd(Object data){
Node temp = this;
while(temp.next!=null)temp=temp.next;
temp.next=new Node(data, null);
}
It's a linked list. You either have to
A) iterate through all your nodes starting at the head, find the last node, then add one.
or
B) keep track of the tail, add to the tail, then update tail to the new last node.
Start from the head:
Node currentNode = headNode;
while (node.getNext() != null) {
currentNode = currentNode.getNext();
}
currentNode.setNext(newNodeForInsertion);
A faster way is to store the last node of the list somewhere so you don't have to go through the whole list.
Recursively navigate through each node until you hit the end.
public void navigate(Node insertNode)
{
if(next == null)
next = insertNode;
else
next.navigate(insertNode);
}
To add to the end, you'd have to walk to the end of the list (i.e., to where next=null) and add a new node there.
In the real world, you'd use an ArrayList for this and not bother with a linked list or manual structure at all.
In your method to add a node, write a while loop that starts at the head and looks to see if the "next node" is null. If it is not, advance to the "next node" and repeat.
Once you are at the node that points to nothing, adding the node is as simple as reassigning the null reference to the node to be added.
A recursive solution:
public void addToEnd(Object data){
if (next==null)
next = new Node(data, null);
else
next.addToEnd(data);
}
Node n = head;
while(n.getNext() != null){
n = n.getNext();
}
n.setNext(nodeToAdd);
That's not sorted, which I can't tell from your question if you want it sorted. Which opens up another whole can of worms such as what do you want to sort on, if you have a linked list of type Object there isn't really anything meaningful to sort on.