I am trying to create a linked list implementation using inner class
package linkedlist;
public class linkedList {
public class Node
{
int data;
public Node next;
public Node(int k)
{
this.data = k;
this.next=null;
}
public Node addToHead(int data)
{
Node node = new Node(data);
Node current = this;
node.next=current;
return node;
}
}
public static void findn(Node head)
{
Node previous=head;
Node current = head;
int i =1;
while(current!=null)
{
if (i==6)
{
//System.out.println(current.data);
previous.next = current.next;
break;
}
previous=current;
current = current.next;
i++;
}
}
public static void main(String args[])
{
linkedList list = new linkedList();
linkedList.Node tail = linkedList.new Node(0);
// list.Node tail = list.Node(0);
Node head = tail;
for (int i=1;i<=20;i++)
{
head = head.addToHead(i);
}
findn(head);
while(head!=null)
{
System.out.println(head.data);
head = head.next;
}
}
}
My question here in the main function i am trying to create a node using the outer class. But the syntax is throwing me an error even though i am following the right syntax. I want to know what is wrong with this statement
"linkedList.Node tail = linkedList.new Node(0);"
A Node, being a non-static inner class, needs an instance of its enclosing class. linkedList is the class name. It doesn't refer to an instance of the class. So it should be
list.new Node()
It would be much clearer if you respected the Java naming conventions: variables start with a lowercase letter, and classes with an uppercase letter.
You should probably create a method within class linkedList, addToTail():
public void addToTail(int k) {
Node tail = new Node(k);
//loop through all the nodes in the list and add "tail" to the end
}
Then you can call lst.addToTail(k) in main(), where lst would be an object of class linkedList.
BTW, it makes the code confusing to read when you begin class names with a lowercase letter. They usually start with an uppercase letter in Java. Calling the class LinkedList (starting with caps) is also confusing because it could be mistaken for the standard java.util.LinkedList, so perhaps you could call it LinkedList0 or something.
Related
I am working on a doubly linked list in Java. So that I can create functions, I'm first working to understand the setup.
I have this code. I have started comments with what each line does. Looking at tutorials and I want to make sure I understand this correctly. I still get a little confused on using classes.
If I create a new node by Node x = new Node(); - I am creating a new node of class Node. So that creates an instance using "static class Node {"
Each Node created contains a int item, Node next, and Node prev, that I will set in my functions. The int item I assume is the contents of the Node.
What does the line "public Node() {}" do?
public class MyDeque {
Node first = null; //instance variable, first is of type node and is set to null
Node last = null; //instance variable, last is of type node and is set to null
int N = 0; //keeping track of number of nodes
static class Node {
public Node() { }
public int item;
public Node next; //next is of type node
public Node prev; //prev is of type node
}
To understand this setup for Double-Linked-List you need to understand how a constructor works; A constructor is like a method, which is used to initialize properties of a class when the object of this class is initialized in memory for the first time.
Let's take your code for an example, I modified it in a proper way to understand why and how constructors used in Java -
public class MyDeque {
Node first;
Node last;
int N;
public MyDeque(){
this.first = null;
this.last = null;
this.N = 0;
}
static class Node {
int item;
Node next;
Node prev;
public Node() {
this.next = null;
this.prev = null;
}
public void setItem(int item) {
this.item = item;
}
public int getItem(){
return this.item;
}
// ... public getters for other items
}
As you can see two constructors public Node(){} and public MyDeque(){} are used to set values for the properties of those objects when they are initialized in memory for the first time.
Later, of course, you can set / unchange / change values of properties using the setter method or using the "." operator but remember constructor will always take place when the objects are initialized or reinitialized in memory for the first time.
I have a linked list I'm given and I need to find the first value in the list via a getFirst method.I need to display an error message and quit the program if the value is null. The linked list is already given to me link so:
class MyLinkedList
{
private class Node // inner class
{
private Node link;
private int x;
}
//----------------------------------
private Node first = null; // initial value is null
//----------------------------------
public void addFirst(int d)
{
Node newNode = new Node(); // create new node
newNode.x = d; // init data field in new node
newNode.link = first; // new node points to first node
first = newNode; // first now points to new node
}
//----------------------------------
public void traverse()
{
Node p = first;
while (p != null) // do loop until p goes null
{
System.out.println(p.x); // display data
p = p.link; // move p to next node
}
}
}
//==============================================
class TestMyLinkedList
{
public static void main(String[] args)
{
MyLinkedList list = new MyLinkedList();
list.addFirst(1);
list.addFirst(2);
list.addFirst(3);
System.out.println("Numbers on list");
list.traverse();
}
}
Here's what I tried out for the method:
public static Node getFirst(Node list)
{
if (list == null)
{
System.out.println("Error!");
System.exit(1);
}
return MyLinkedList.first;
}
I know this isn't exactly right, we just started this in my class so I'm having trouble understanding what's going on with it. Thank you!
I think you should look at https://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html and get an idea for the behavior of a linked list initially. Once you have an idea on how it behaves, you can think about how to add functionality around it. Right now you just have a single method which you call more than you should. What also might help is to create an interface and document it so you know what each method should do.
You should check that first isn't null in order to do what you describe in the question. Also, it is kind of weird that the first node autoreferences itself because usually it is left in null until you add another node
notice that the first value is linked to the first Node with is null. Then you have to check two things
Node == null (you got this)
Node.next == null (you have to do this)
When Node.next == null. It means that Node is first value because it is linked to the initial Node with is null.
Then you have
public static Node getFirst(Node list)
{
// if the list is empty
if (list == null)
{
System.out.println("Error!");
System.exit(1);
} else if(list.link == null) {
// this is the first value!
return list;
} else {
// keep searching recursive with the next Node
return getFirst(list.link);
}
}
The class MyLinkedList in your question follows the pattern of a stack data structure(At the time when i am writing this answer). That is: ever time you add a new element, the new element replaces the previously added element as the first element.
I guess you want to get 1 as your first element, if you have added elements 1,2,3 in that order. Correct me if i am wrong.
In that case your linked list and it's retrieval should be like this:
(Note: i have avoided private vars , public getter , settter , etc; to make code easily readable. But readers should add them.)
class Node{ int x; Node next; }
class LinkedList
{ Node head,tail;
void add(int y)
{ Node node = new Node();
node.x=y;
if(head==null)
head = tail = node;
else
tail = tail.next = node;
}
int getFirst()
{ if(head!=null)
return head.x;
else
throw new java.util.NoSuchElementException("List is empty");
}
}
If you look at java.util.LinkedList, you will find methods that are conventionally used in linked lists. If this is not a homework question, then i suggest you do not reinvent the wheel. Just use the existing libraries.
If you have to use the stack data structure, and you cannot change it, then i suggest you have to change your getFirst() like this:
int getFirst()
{ if(tail!=null)
return tail.x;
else
throw new java.util.NoSuchElementException("List is empty");
}
If you not allowed to add Node tail in your code, then your getFirst() will look like this:
int getFirst()
{ if(head==null)
throw new java.util.NoSuchElementException("List is empty");
Node node = head;
while(node.next!=null)
node=node.next;
return node.x;
}
Hi it's been a while since I've written java and I can't seem to find what is wrong with this code. I'm implenting deleting a node from a linked list but my program won't compile. I keep getting:
error: non-static variable this cannot be referenced from a static context
Node head = new Node();
It has an error for all my new Node() instances in my main method.
public class NodeDelete{
class Node {
int data;
Node next;
public Node(){ }
}
Node Delete(Node head, int position) {
// Complete this method
int index = 0;
Node current = head;
if (position == 0 ){
head = head.next;
}
else{
while (index < (position - 1)){
current = current.next;
}
current.next = current.next.next;
}
return head;
}
public static void main(String[] args) {
Node head = new Node();
head.data = 0;
Node node1 = new Node();
node1.data = 1;
Node node2 = new Node();
node2.data = 2;
head.next = node1;
node1.next = node2;
}
}
Either make the Node class static. OR take out Node class from the NodeDelete class. That will solve the issue.
The Node class is a non-static inner class of NodeDelete, so it is like a member of the NodeDelete class. To access any member in the static context, instance of the class is required. That is why you are getting the compile time error here.
Note : The constructor you have defined in the Node is same as the default constructor. So no need to define it. It is redundant.
Making Node class static:
static class Node {
int data;
Node next;
public Node(){ } // This is same as the default constructor. So this can be remove.
}
OR
Take out the same implementation from the NodeDelete class.
Node is a non-static inner class. Therefore a instance of the containing class is needed to construct the instance:
NodeDelete nd = ...
Node node = nd.new Node();
Alternatives:
Make Node a static inner class
Make Node a top level class
Since there is no reference to a NodeDelete in Node's methods I recommend making Node static.
Another option not given yet, though not my favorite, would be to instantiate an instance of the class which contains the main method then use it to instantiate the inner class. Like so...
NodeDelete nd = new NodeDelete(...);
Node n = nd.new Node(...);
I have a linked list using objects of class "ListNode"
ListNode has the following non static methods:
getValue()
setValue(Object obj)
getNext()
setNext(ListNode ln)
It's constructor takes a value and a next.
In my main method in my driver class, create my linked list:
ListNode head = new ListNode("Overflow!", null);
head = new ListNode("Stack", head);
head = new ListNode("in", head);
head = new ListNode("is", head);
head = new ListNode("This", head);
I have a method called printList(ListNode ln).
I call it twice consecutively in my main method like this:
printList(head);
System.out.println();
printList(head);
My method looks like this:
public static void printList(ListNode head)
{
while(head != null)
{
System.out.print(head.getValue()+" ");
head = head.getNext();
}
}
In my method, the reference is changed to point to a different object each time in the while loop. So after I exit the method, the reference "head" should be pointing to a null, right? However, when the printList(head) is called the second time, it magically prints all the elements in the list!
Here is what the jGrasp console shows:
----jGRASP exec: java StackOverflowQuestionExampleClass
This is in Stack Overflow!
This is in Stack Overflow!
----jGRASP: operation complete.
Here is the listnode class my teacher told me to use:
//Thomas Bettge, TJHSST, 10-20-2006
public class ListNode
{
private Object value;
private ListNode next;
public ListNode(Object v, ListNode n)
{
value=v;
next=n;
}
public Object getValue()
{
return value;
}
public ListNode getNext()
{
return next;
}
public void setValue(Object newv)
{
value=newv;
}
public void setNext(ListNode newn)
{
next=newn;
}
}
Confusion is probably stemming from the fact that you have 2 labels with the same name "head". The "head" argument in the printList method is a new reference to the object that was passed in. reassigning it doesn't affect the target of the original reference (in the sense that t won't cause it to reference something else. an aside: changes to the state of the referenced object will have an effect, as it's the same object, regardless of what is referencing it).
might make it clearer to look at your code like this:
public void yourMainMethod() {
ListNode head = new ListNode("Overflow!", null);
head = new ListNode("Stack", head);
head = new ListNode("in", head);
head = new ListNode("is", head);
head = new ListNode("This", head);
printList(head);
System.out.println();
printList(head);
}
//note different name, to clarify this is a separate reference
public static void printList(ListNode node) {
while(node != null)
{
System.out.print(node.getValue()+" ");
node = node.getNext();
//node.setValue(new Object());//note that this would change the state inside the ListNode passed in
}
}
head is a local reference inside the method print.
Reassigning into it doesn't affect the head reference outside the method.
I have 2 questions about linked lists so i figured i'll post them in one question.
first i'll show my node class and the copy constructor and constructor from a string
class CharNode
{
private char letter;
private CharNode next;
public CharNode(char ch, CharNode link)
{
letter = ch;
next = link;
}
public void setCharacter(char ch)
{
letter = ch;
}
public char getCharacter()
{
return letter;
}
public void setNext(CharNode next)
{
this.next = next;
}
public CharNode getNext()
{
return next;
}
}
copy constructor
// copy constructor
public CharList(CharList l)
{
CharNode pt = head;
while(pt.getNext() != null)
{
this.setCharacter() = l.getCharacter();
this.setNext() = l.getNext();
}
}
constructor from string
// constructor from a String
public CharList(String s)
{
head = head.setCharacter(s);
}
when i try to compile i get an error for my copy constructor it says that it cant find the symbol this.setCharacter()... and the l.setCharacter()...
am i just doing it completely wrong?
and with my constructor from a string i know thats wrong. i thought about using the charAt() but how would i know when to stop the loop to do that? is that a good approach to take?
any help would be appreciated.
in your CharList constructor, this refers to the CharList class, which doesn't have a setCharacter() method (CharNode does). also, when you call a method in java, you need to pass the parameter, e.g. setFoo(newFoo), not setFoo() = newFoo
Your set character method is probably in your node, not in your list. You also need to be moving your pointer along. What I mean is, where do you ever "go to the next node"?
Your copy constructor is for the class CharList, while setCharacter is defined in CharNode.
this in the copy constructor references the current instance of the CharList object the constructor is defined on. l is also a CharList in your code rather than a CharNode which defines setCharacter.
The copy constructor should be defined in the CharNode class.
In your "copy constructor" you would need to go through the list being passed in starting with its head, and create new nodes for your new list ...
public CharList(CharList l)
{
// Whatever method your CharList provides to get the
// first node in the list goes here
CharNode pt = l.head();
// create a new head node for *this* list
CharNode newNode = new CharNode();
this.head = newNode;
// Go through old list, copy data, create new nodes
// for this list.
while(pt != null)
{
newNode.setCharacter(pt.getCharacter());
pt = pt.getNext();
if (pt != null)
{
newNode.setNext(new CharNode());
newNode = newNode.getNext();
}
}
}
As for creating a list from a String ... same concept except you iterate through the string rather than another CharList
for (int i = 0; i < myString.length(); i++)
{
...
newNode.setCharacter(myString.charAt(i));
...