I am creating a singly linked circular list and I don't seem to understand why it is not working. Here is my code. Would someone help me and point out what am I doing wrong? I am able to add the first node but I don't understand how to add the second node. Could someone show me how to change it. I think my list is traversing endlessly that's why.
public class CircularList <E> {
private Node<E> head;
private class Node <E>
{
E data;
Node <E> next;
public Node(E data, Node<E> next)
{
this.data = data;
this.next = next;
}
public Node(E data)
{
this.data = data;
this.next = null;
}
}//node
public CircularList()
{
head = null;
}
public void add(E data)
{
Node <E> temp = new Node <E> (data);
if(head==null)
{
head=temp;
temp.next=temp;
System.out.println(head.next.data);
}
else
{
Node<E> temp2 = head.next;
while(temp2!=head)
{
if(temp2.next==head)
{
temp2.next=temp;
temp.next=head;
}
temp2=temp2.next;
}
}
}
Update your else part with this;
Node<E> temp2 = head;
while(temp2.next != head)
{
temp2=temp2.next;
}
temp2.next=temp;
temp.next=head;
If you would like to make your singly linked list circular, it would be a good idea to have a tail, then your code can be something along the lines of (pseudo code)
function addElement(data){
Node n = new Node(data)
if(list.isEmpty() ){
head = n
tail = n
n.setNext(n)
} else {
n.setNext(head)
tail.setNext(n)
head = n
}
}
Related
So I wrote my own linked list (and list node) in Java as a part of a homework.
Now, I'm trying to erase entries, but the function is not working.
I know the concept:
Search for node keeping the previous;
Tell previous node to point to next node;
Return or stop using the node so GC erases it.
For some reason it is not working. I can delete the node with the same value over and over. I'm afraid it is something related to Java pointers.
The code:
Node:
public class SimpleNode<E> {
private E value;
private SimpleNode<E> next;
public SimpleNode() {
this.value = null;
this.next = null;
}
public NoSimples(E data, SimpleNode<E> ref) {
this.value = data;
this.next = ref;
}
// Getters and Setters
}
List:
public class LinkedList<E> implements Iterable<SimpleNode<E>> {
private SimpleNode<E> head;
private int size = 0;
public LinkedList() {
this.head = new SimpleNode<E>();
}
public void add(SimpleNode<E> node) {
this.addFirst(node.getValue());
}
public void addFirst(E item) {
SimpleNode<E> nonde = new SimpleNode<E>(item, this.head);
this.head = node;
size++;
}
public void add(E value) {
this.addFirst(value);
}
public SimpleNode<E> removeFirst() {
SimpleNode<E> node = this.head;
if (node == null) {
return null;
} else {
this.head = node.getNext();
node.setNext(null);
this.size--;
return node;
}
}
public SimpleNodes<E> remove(E value) {
SimpleNode<E> nodeAnt = this.head;
SimpleNode<E> node = this.head.getNext();
while (node != null) {
if (node.getValue()!= null && node.getValue().equals(value)) {
nodeAnt.setNext(node.getNext());
node.setNext(null);
return node;
}
nodeAnt = node;
node = node.getNext();
}
return null;
}
// Other irrelevant methods.
}
Multiple Problems :
Think if you have a list 1,2,3,4. Now, if you try to remove 1, your code fails.
nodeAnt = node should be nodeAnt = nodeAnt.getNext(). Remember, the're all references, not Objects
Also, a recursive way might be easier to understand. For example, Here is how I implemented it
public void remove(E e){
prev = head;
removeElement(e, head);
System.gc();
}
private void removeElement(E e, Node currentElement) {
if(currentElement==null){
return;
}
if(head.getData().equals(e)){
head = head.getNext();
size--;
}else if(currentElement.getData().equals(e)){
prev.setNext(currentElement.getNext());
size--;
}
prev = prev.getNext();
removeElement(e, currentElement.getNext());
}
Note: I delete all occurrences of the Element, as I needed it. You may need it to be different.
My Node class:
public class Node<T>
{
protected T data;
protected Node<T> next;
protected Node<T> previous;
public Node()
{
this.data = null;
this.next = null;
this.previous = null;
}
public Node(T data)
{
this.data = data;
this.next = null;
this.previous = null;
}
public Node(T data, Node<T> next, Node<T> previous)
{
this.data = data;
this.next = next;
this.previous = previous;
}
public T getData()
{
return data;
}
public void setData(T data)
{
this.data = data;
}
public Node<T> getNext()
{
return next;
}
public void setNext(Node<T> next)
{
this.next = next;
}
public Node<T> getPrevious()
{
return previous;
}
public void setPrevious(Node<T> previous)
{
this.previous = previous;
}
}
My LinkedList class:
public class LinkedList<T extends Node<T>>
{
private Node<T> head;
private Node<T> tail;
private Node<T> currNode;
public LinkedList()
{
head = null;
tail = null;
currNode = null;
}
public LinkedList(Node<T> head)
{
this.head = head;
tail = head;
currNode = head;
}
public void resetHead()
{
currNode = head;
}
public void add(T data)
{
Node<T> newNode = new Node<T>(data);
newNode.next = null;
if(head == null)
{
head = newNode;
}
else
{
tail.next = newNode;
newNode.previous = tail;
tail = newNode;
}
}
public void addHead(T data)
{
Node<T> newNode = new Node<T>(data);
newNode.next = head;
head.previous = newNode;
head = newNode;
}
public void addAfter(T data, Node<T> previousNode)
{
Node<T> newNode = new Node<T>(data);
newNode.next = previousNode.next;
previousNode.next = newNode;
}
public void addBefore(T data, Node<T> nextNode)
{
Node<T> newNode = new Node<T>(data);
newNode.next = nextNode;
nextNode.previous = newNode;
}
public void delete(Node<T> nodeToDelete)
{
(nodeToDelete.getNext()).setPrevious(nodeToDelete.getPrevious());
(nodeToDelete.getPrevious()).setNext(nodeToDelete.getNext());
nodeToDelete.setNext(null);
nodeToDelete.setPrevious(null);
}
public boolean hasNext()
{
if(head == null)
{
return false;
}
else if(currNode.next != null)
{
currNode = currNode.getNext();
return true;
}
else
{
return false;
}
}
public boolean hasPrevious()
{
if(tail == null)
{
return false;
}
else if(currNode.previous != null)
{
currNode = currNode.getPrevious();
return true;
}
else
{
return false;
}
}
public Node<T> getHead()
{
return head;
}
public void setHead(Node<T> head)
{
this.head = head;
}
public Node<T> getTail()
{
return tail;
}
public void setTail(Node<T> tail)
{
this.tail = tail;
}
public Node<T> getCurrNode()
{
return currNode;
}
public void setCurrNode(Node<T> currNode)
{
this.currNode = currNode;
}
}
The error crops up when attempting to use any of the add/insert methods in LinkedList. For example, if I try to use the add(T data) method, like so: listOfChars.add('B');, I get the following error: The method add(Node) in the type LinkedList is not applicable for the arguments (char). What I expect it to do is to accept the data (in this case, the char 'B'), create a new node with 'B' as the data, and then put it in the linked list after the last node in the list. From my understanding, the method is expecting a Node instead of any generic data type, such as a char.
After doing some researching, I think somewhere in my TestLinkedList class, I have declared the LinkedList object incorrectly:
public class TestLinkedList
{
public static void main(String[]args)
{
Node<Character> n1 = new Node<Character>('A');
LinkedList listOfChars = new LinkedList(n1);
listOfChars.add('B');
}
}
but I can't figure out how to declare it correctly. I've tried LinkedList<Character>, LinkedList<Node>, LinkedList<Node<T>>, and LinkedList<Node<Character>>, but none of them are correct. Any help would be appreciated as this is my first time using generics and I am just trying to learn how to apply it to a Linked List I've made.
You need to fix two things. First, the class declaration of LinkedList says:
public class LinkedList<T extends Node<T>> {
which means that T has to be both a Node and the element of a Node. This doesn't work with Character since a Character is not an instance of Node. If you remove the constraint so that T can be any value, it works with Character.
public class LinkedList<T> {
Next you should add the generic part to the main file for the listOfChars as well:
LinkedList<Character> listOfChars = new LinkedList<Character>(n1);
Also make sure that you have imported the right LinkedList and not the java standard class.
You simply have to rewrite LinkedList from
LinkedList<T extends Node<T>>
to
LinkedList<T>
since in the code of LinkedList you already state that you are using Node objects.
You can use it like this:
public static void main(String[]args)
{
Node<Character> n1 = new Node<>('A');
LinkedList<Character> listOfChars = new LinkedList<>(n1);
listOfChars.add('B');
}
I think its a combination of both Todd's and Adams answer
public class LinkedList<T extends Node<T>>
to
public class LinkedList<T>
and
LinkedList<Character> listOfChars = new LinkedList<>(n1);
As you can infer from the error The method add(Node) in the type LinkedList is not applicable for the arguments (char)
This is a type error, your add method expects a Node but in the main you call add with type character.
Your LinkedList class is expecting an object of type T extends Node. Which would imply a custom class that extends your Node object, however that is not what you are looking to use to add objects to the linkedlist.
Ok, so your class declaration
public class LinkedList<T extends Node<T>>
is saying 'This is a class LinkedList parameterised by T where T is a subtype of Node<T>
This means if you wanted T = Character for example, you would need Character to be a subtype of Node<Character>, which doesn't really make sense.
You probably want to just parameterise your class by T eg public class LinkedList<T>
Then you can go LinkedList<Character> listOfChars = new LinkedList<Character>(n1)
or more succinctly LinkedList<Character> listOfChars = new LinkedList<>(n1) as the second generic parameter can be inferred
Create your LinkedList like this:
LinkedList<Character> listOfChars = new LinkedList<>(n1);
EDIT:
M4ver1k is right that this alone won't fix it. I missed the part that Adam Arold pointed out. Adam's answer fixes the problem and should be accepted. My answer just prevents the LinkedList from being implicitly defined as a LinkedList<Object>.
.
I'd like to add new nodes into the list without removing/substituting the dummy node head, i.e. head is always null and the list would start from head.next (head -> node -> node -> node). I'm having trouble with the syntax of the dummy node and Im not sure if Im doing it right at all. Could smb please take a look? Thanks in advance!
Im getting a nullPointer in this line of the constructor:
this.head.next = null;
CODE
package SinglyLinkedList;
import java.util.*;
public class Tester {
public static void main(String[] args){
LinkedList<Integer> myList = new LinkedList<Integer>();
myList.insert(1);
myList.insert(2);
myList.insert(3);
myList.displayList();
}
}
Class Link
package SinglyLinkedList;
import java.util.Iterator;
public class Node<T> {
public T data;
public Node<T> next;
public Node(T data){
this.data = data;
}
public void display(){
System.out.print(this.data + " ");
}
}
class LinkedList<T> implements Iterable<T>{
private Node<T> head;
private int size;
public LinkedList(){
this.head = null;
this.head.next = null;
this.size = 0;
}
public boolean isEmpty(){
return head == null;
}
public void displayList(){
if(head.next == null){
System.out.println("The list is empty");
}
else{
Node<T> current = head.next;
while(current != null){
current.display();
current = current.next;
}
}
}
public void insert(T data){
Node<T> newNode = new Node<T>(data);
if(head.next == null){
head.next = newNode;
}
else{
newNode.next = head.next;
head.next = newNode;
}
size++;
}
#Override
public Iterator<T> iterator() {
// TODO Auto-generated method stub
return null;
}
}
I guess you have misunderstood the concept of linked lists. The member variable head points to the start address of the linked list. It cannot be null. head.next should point to the second element while head itself points to the first element. Moreover, you don't have to change the value of head while adding new nodes to the list unless the node you insert is supposed to be placed at the beginning of the linked list. In that case, you need to update head to point to the new node. For inserting nodes in the middle or at the end of the linked list, this is not required.
Further reading:
http://crunchify.com/how-to-implement-a-linkedlist-class-from-scratch-in-java/
http://www.tutorialspoint.com/java/java_linkedlist_class.htm
The question is this:
Define a constructor that takes a TreeSet as a parameter and initializes a linked list with the elements in the set. The new list must be sorted in increasing lexicographic order.
This method is to be implemented using the class below:
public class LinkedList<T extends Comparable<T>> {
private class Node{
private T data;
private Node next;
private Node(T data){
this.data = data;
next = null;
}
}
private Node head;
public LinkedList(){
head = null;
}
Now I know a TreeSet is inherently sorted so all I'd really have to do here is take the element from the TreeSet and put it to the front of this linked list. But I'm having trouble retrieving the element from the set and adding it to the LinkedList. I wrote a private helper add(T data) method and am using it but I don't know if this is how I should approach it. I'm new to data structures so have little idea about sets and their implementations.
public class LinkedList<T extends Comparable<T>> {
private class Node{
private T data;
private Node next;
private Node(T data){
this.data = data;
next = null;
}
}
private Node head;
public LinkedList(){
head = null;
}
public void add(T data){
Node n = new Node(data);
if(head == null){
head = n;
}
else{
n.next = head;
head = n;
}
}
public LinkedList(TreeSet<T> test){
Iterator<T> itr = test.iterator();
while(itr.hasNext()){
this.add(itr.next());
}
}
The main problem you have to solve is that you need to add each item to the end of the list not the start.
Adding a node to the start of the list is easy:
public void addToHead(T data) {
Node node = new Node(data);
node.next = head;
head = node;
}
Adding to the end is harder because you don't have a reference to the tail. But the solution is fairly simple: in the constructor you are developing, keep a reference to the tail of the list so that you can add each value at the end of the links rather than the start.
The question includes "increasing lexicographic order."
My solution is without helper method:
public LinkedList(TreeSet<T> test){
Node currNode = null;
for(T data : test) {
Node newNode = new Node(data);
if(head == null) {
head = newNode;
currNode = head;
}
else {
currNode.next = newNode;
currNode = currNode.next;
}
}
}
I am trying to implement the add method for the linkedlist , it should take any data type, but I am kind of lost and is not working, any help will be appreciated.
public class LinkedList <T>extends AbstractList {
private class Node {
T data;
Node next;
Node(T data, Node next) {
this.data = data;
this.next = next;
}
Node(T data) {
this(data, null);
}
}
Node first;
Node last;
public LinkedList() {
first = null;
last = null;
}
#Override
public boolean add(T item) {
Node newNode = new Node((T)item);
if (isEmpty()) {
first = newNode;
last = first;
return true;
}
last.next = newNode;
last = null;
return true;
}
}
You don't tell us your concrete problem, so we can't fix it, only guess.
One issue I see though is that you extend AbstractList as a raw (nongeneric) type - your declaration should be instead
public class LinkedList<T> extends AbstractList<T> { ... }
You need:
last.next = newNode;
last = newNode;
Be careful that you understand why.
Before you add the new node, last is a reference to the last entry in the list.
What you want to do is to point its next reference to this new node.
The second line then updates last to refer to this new one too.