I have an assignment in my CS class about circular doubly linked lists. We are given a Node class that sets up the links and such.
public class Node {
private Node previous, next;
private Object data;
public Node(Object data) {
this.data = data;
}
public Node() {
}
public Node(Object data, Node previous, Node next) {
this.previous = previous;
this.next = next;
this.data = data;
}
public Node getPrevious() {
return previous;
}
public void setPrevious(Node previous) {
this.previous = previous;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
and we are tasked with implementing a few methods. In the list class there is one Node created called 'base'
public class DList {
private Node base;
public DList() {
}
all of the methods require some form of traversing the list. From what I understand setting up a temp node to be equal to base.getNext() will give me the first node of the list and testing if temp != base will be my check for reaching the end of the list since the base node serves as an anchor for the rest of the nodes (if my understanding is correct).
However, when I try to do bits of code such as:
public int size() {
int count = 0;
if (base.getNext() == base)
return count;
else {
Node temp = base.getNext();
while (temp != base) {
temp = temp.getNext();
count++;
}
}
return count;
}
I get a null pointer exception at the line where I say Node temp = base.getNext(); and for the life of me I cannot understand why, because like I said earlier I thought that base.getNext() would be the first element of my list.
There is no need for a dummy base node. In that case base initially is null.
In that case:
public int size() {
int count = 0;
if (base != null) {
Node temp = base;
do {
temp = temp.getNext();
count++;
} while (temp != base);
}
return count;
}
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 am having trouble doing a homework assignment involving stacks and nodes in Java. I understand the concept of Stacks but am confused with Nodes. The assignment is to make a program using Stacks (Not java.util.Stack) that checks a mathematical expression for correct pairs of (), [], and {}s. We already have the Node program.
So basically my problem is I would like some help completing the Push Method of my PStack class.
PStack.java
class PStack {
private Node top;
public PStack() {
top=null;
}
public boolean isEmpty() {
return top==null;
}
public int pop() {
Node top1 = top;
top = top.getNext();
return top1.getData();
}
public void push(Node n) {
}
public int peek() {
return top.getData();
}
}
Node.java
public class Node {
private int data;
private Node nextnode;
public Node(int intial) {
data = intial;
nextnode = null;
}
public int getData() {
return data;
}
public Node getNext() {
return nextnode;
}
public void setData(int newdata) {
data = newdata;
}
public void setNode(Node next1node) {
nextnode = next1node;
}
}
I tried:
public void push(Node n) {
Node next = n;
top.getNext().setNode(n);
}
Result:
Exception in thread "main" java.lang.NullPointerException
at javaclass.stack.pStack.push(pStack.java:24)
at javaclass.stack.StackDriver.main(StackDriver.java:17)
public void push(Node n) {
n.setNode(top);
top = n;
}
Edit:
BTW, this is an odd implementation of a stack. It looks like it wants to be a stack of int primitives. Both peek() and pop() return an int. But then push takes an argument that should be an internal construct of the stack itself. It shouldn't take a Node object as an argument. It should take an int argument and wrap it with the Node object internally.
Also, Node.setNode should be named Node.setNext. It's just more consistent with what you are doing. A linked list node has a "next" member and a double linked list node has "next" and "previous" members. The getters and setters of the node object should be appropriately named for those members.
Like this:
PStack.java
public class PStack {
private Node top;
public boolean isEmpty() {
return top==null;
}
public int pop() {
Node top1 = top;
top = top.getNext();
return top1.getData();
}
public void push(int data) {
Node newtop = new Node(data);
newtop.setNext(top);
top = newtop;
}
public int peek() {
return top.getData();
}
}
Node.java
public class Node {
private int data;
private Node next;
public Node(int data) {
this.data = data;
}
public int getData() {
return data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
I am writing a program where i have to create a Double linked list full of nodes which user can insert with own values.I have methods to insert the new node into different parts of the list(front, in position,tail). Each node has two informations, one String and the oder INT (both are set by user after creating a new node.
My problem here is how can i set the first information as String, (in the exaple i give there is the version with bot elements INT, but the first one must be string and this is where i need help)
public void insertInFirstPosition(int information,int key) {
Node n = new Node(information,key, null, null);
if (head == null) {
n.setLinkNext(n);
n.setLinkPrev(n);
head = n;
tail = head;
} else {
n.setLinkPrev(tail);
tail.setLinkNext(n);
head.setLinkPrev(n);
n.setLinkNext(head);
head = n;
}
size++;
}
HERE IS THE NODE CLASS `
public class Node {
private int data;
private int informazione;
private Node next, prev;
/* Constructor */
public Node() {
next = null;
prev = null;
data = 0;
informazione = 0;
}
public Node(int i,int k, Node n, Node p) {
data = i;
informazione = k;
next = n;
prev = p;
}
/* Function to set link to next node */
public void setLinkNext (Node n) {
next = n;
}
/* Function to set link to previous node */
public void setLinkPrev(Node p) {
prev = p;
}
/* Funtion to get link to next node */
public Node getNext() {
return next;
}
/* Function to get link to previous node */
public Node getPrev() {
return prev;
}
/* Function to set information to node */
public void setInformazione(int i) {
informazione = i;
}
/* Function to get data from node */
public int getInformazione() {
return informazione;
}
/* Function to set data to node */
public void setData(int d) {
data = d;
}
/* Function to get data from node */
public int getData() {
return data;
}
}`
in this code you can only enter INT values for both of the node slots, the second slot is fine, must be an int, meanwhile the first slot have to be an String.
Thank all for help.
You should make your Node class generic, and let it accept any class as data.
class Node<T> {
T data;
Node<T> prev;
Node<T> next;
public Node (T data, Node<T> prev, Node<T> next) {
this.data = data;
this.prev = prev;
this.next = next;
}
}
Now you can define a class (let's call it SomeClass) that contains all the properties you want to store in a given Node, and create a Node with:
Node<SomeClass> n = new Node<SomeClass>(new SomeClass(information,key), null, null);
I'm trying to understand LinkedLists(Single LinkedList to be precise).
I heard/read that delete and add operation will be performed with O(1) complexity and I'm still not getting how to implement with O(1) complexity for these two operation.
Below is my implementation in java(NOTE: I don't know c, c++ coding, So I recently started understanding data structures).
public class Node
{
private Integer data = null;
private Node next = null;
private int size = 0;
public Node()
{
}
private Node(Integer data)
{
this.data = data;
}
public boolean add(Integer data)
{
if (null == data) return false;
if (null == this.data)
{
this.data = data;
}
else
{
if (null == this.next)
{
this.next = new Node(data);
}
else
{
this.next.add(data);
}
}
size += 1;
return true;
}
public Integer getDataAt(int index)
{
if (index == 0)
{
return this.data;
}
else
{
return this.next.getDataAt(index - 1);
}
}
public int getSize()
{
return size;
}
}
Please suggest me to edit as of now add(data) to make it O(1) complexity.
Only Adding and Removing operation in LinkedList is O(1) but traversing to the node you want to remove or add is an O(N) operation
You can achieve the O(1) complexity if you keep the reference to your last added element so you can put add new Node to the last traversed element's next Node.
In linkedList if you have head and tail pointer to point first and last of node linkedlist then in constant time you can add and remove in first or last position of the node.If you want to delete an element you have to find that element and in worst case that element will be in last .In doubly linkedlist you can start from start and end so you have to traverse till so in worst case it will be O(n).
Thank you for all your support, as a NOOB in data structure I want to understand how ds workds rather than copy pasting from someone's else implementation.
Neeraj Jain & Gati Sahu's explanations/answer helped me to achieve what I'm looking for add(data) in LinkedList with O(1) complexity.
So what I did is "Segregate Plain Node class and create LinkedList class with operations.
class Node
{
private Integer data = null;
private Node next = null;
public Node(Integer data)
{
super();
this.data = data;
}
public Integer getData()
{
return data;
}
public Node getNext()
{
return next;
}
public void setData(Integer data)
{
this.data = data;
}
public void setNext(Node next)
{
this.next = next;
}
}
public class LinkedList
{
Node head;
Node end;
public Node getHead()
{
return head;
}
public boolean add(Integer data)
{
if (null == head)
{
head = new Node(data);
end = head;
}
else
{
addAtEnd(data);
}
return true;
}
public void addAtEnd(Integer data)
{
end.setNext(new Node(data));
end = end.getNext();
}
public void addAtFirst(Integer data)
{
Node tmpNode = head;
head = new Node(data);
head.setNext(tmpNode);
}
}
I am currently learning Doubly Linked Lists.
I have managed to convert write a doubly linked list that was nearly 100% functional. However I need to learn how to write it with tail recursion.
Below is my DLLNode code:
public class DLLNode
{
private DLLNode previous;
public DLLNode next;
private String value;
public DLLNode(String value)
{
this.value = value;
this.previous = previous;
this.next = next;
}
public DLLNode(String value, DLLNode next, DLLNode previous)
{
this.value = value;
this.next = next;
this.previous = previous;
}
public String GetDataItem()
{
return value;
}
public void setDataItem()
{
this.value = value;
}
public DLLNode GetPreviousNode()
{
return previous;
}
public void setPrevious(DLLNode previous)
{
this.previous = previous;
}
public DLLNode GetNextNode()
{
return next;
}
public void setNextNode(DLLNode next)
{
this.next = next;
}
public void addItem(String value) {
if(this.next == null) {
// Stopping condition
DLLNode newNode = new DLLNode(value);
this.next = newNode;
} else {
// Recurse
this.next.addItem(value);
}
}
}
I have managed to get my AddItem working using tail recursion and I'm now looking into getting delete Item working. I'm guessing that like addItem I need deleteItem adding to my DLLNode.
Below is my DoublyLinkedList class:
public class DoublyLinkedList
{
private int noOfItems;
private DLLNode head;
private DLLNode tail;
// Default constructor
public DoublyLinkedList()
{
head = null;
tail = null;
this.noOfItems = 0;
}
public void DeleteItem(int index)
{
if (index ==0)
{
System.out.println("Out of Bounds");
}
if (index > noOfItems)
{
System.out.println("Out of Bounds");
}
if (head == null)
{
System.out.println("No Item to remove");
}
else if (index == 1)
{
head = head.GetNextNode();
noOfItems--;
}
else
{
int position = 0;
DLLNode currentNode = head;
while (currentNode != null) {
if (position == index-1) {
currentNode.setNextNode(
currentNode.GetNextNode().GetNextNode());
noOfItems--;
break;
}
currentNode = currentNode.GetNextNode();
position++;
}
}
}
}
Any tips on where I can get started with converting this code would be greatly appreciated.
Kind Regards,
Ben.
P.S. Apologies for the way the code has formatted - I've tried to fix it but it won't seem to sort. Can anyone good at formatting code on her please try and sort it out?
private void DeleteItemHelper(final int indexToDelete, int curIndex, DLLNode curNode) {
if (curIndex == indexToDelete) {
// Handle removing a node with both a previous and next nodes.
}
else {
DeleteItemHelper(indexToDelete, curIndex + 1, curNode.getNextNode());
}
}
public void DeleteItem(int index) {
DeleteItemHelper(index, 0, head);
}
Without further testing I think that you are forgetting to re-set the head reference of the node following the removed node:
if (position == index-1) {
// Tail of currentNode is set to the node following
// next node, but head of that node still points to the
// node which should be removed from list
currentNode.setNextNode(
currentNode.GetNextNode().GetNextNode());
noOfItems--;
break;
}