I'm having trouble figuring out why my code won't parse through the ListNodes in the Lists, in order to add a new String as a ListNode. I'm trying to write the function add(String s), to add a new ListNode to the List. If the list is empty, I just add the String as a ListNode, and if not, I parse through using node and myNext, and then if node.myNext is null, I replace it with the newly created ListNode. What is the reason this isn't working? It either does not throw an output or it says it is out of bounds.
public class List {
private ListNode myHead;
private int mySize;
public List() {
this.myHead = null;
this.mySize = 0;
}
public class ListNode {
public String myData;
public ListNode myNext;
public ListNode(String element, ListNode next) {
this.myData = element;
this.myNext = next;
}
public ListNode(String element) {
this(element, null);
}
public boolean isEmpty() {
return this.length() == 0;
}
public void add(String s) {
if(this.isEmpty() == true) {
this.addToFront(s);
}
else {
this.mySize++;
for(ListNode node = this.myHead; node.myData != null; node = node.myNext) {
if(node.myNext == null) {
ListNode lno = new ListNode(s, null);
node.myNext = lno;
}
else {
node.myData = node.myData;
}
}
}
}
In you ListNode you can't access methods and variables of your List class.
Assuming that you want to add the new String at the top of your List you should do something like this:
public class List {
private ListNode myHead;
private int mySize;
public List() {
this.myHead = null;
this.mySize = 0;
}
public boolean isEmpty() {
return this.mySize == 0;
}
public void add(String s) {
this.myHead = new ListNode(s, myHead);//add new String as head element
this.mySize++;
}
}
public class ListNode {
public String myData;
public ListNode myNext;
public ListNode(String element, ListNode next) {
this.myData = element;
this.myNext = next;
}
public ListNode(String element) {
this(element, null);
}
}
If you want to add it at the end of your List you can try it like this:
public void add(String s) {
if(this.isEmpty()){
this.myHead = new ListNode(s, myHead);//add new String as head element
}else{
ListNode node = this.myHead;
while (node.myNext != null){
node = node.myNext;
}
//now you hav the last node of your list
node.myNext = new ListNode(s,null);
}
this.mySize++;
}
The code you have pasted is not complete.
Also, If I am correct, your List is having the ListNodes and thus, it is your List where you should put methods to check if it is Empty (does not have any ListNodes in it) or add, delete, count, search etc. functions.
For isEmpty(), There is no length() defined, so simply check the size to be == 0.
For add(), if it is empty just point myHead to your new ListNode; If you have to add in end, iterate the myHead using a currentNode reference, till its next is null and add.
If it is to be in middle somewhere, you will need to check for ListNode myData to decide where it fits white moving from myHead towards null and once you find a place to insert, you will need to change the [PrevNode] -> new ListNode -> [nextNode]
Related
I have a List
public class SinglyLinkedList {
//---------------- nested Node class ----------------
private static class Node {
private String element; // reference to the element stored at this node
private Node next; // reference to the subsequent node in the list
public Node(String e, Node n) {
element = e;
next = n;}
public String getElement( ) { return element; }
public Node getNext( ) { return next; }
public void setNext(Node n) { next = n; }
}
// instance variables of the SinglyLinkedList
private Node head = null; // head node of the list (or null if empty)
private Node tail = null; // last node of the list (or null if empty)
private int size = 0; // number of nodes in the list
public SinglyLinkedList( ) { } // constructs an initially empty list
// access methods
public int size( ) { return size; }
public boolean isEmpty( ) { return size == 0; }
public String first( ) {
// returns (but does not remove) the first element
if (isEmpty( )) return null;
return head.getElement( );
}
public String last( ) {
// returns (but does not remove) the last element
if (isEmpty( )) return null;
return tail.getElement( );
}
// update methods
public void addFirst(String e) {
// adds element e to the front of the list
head = new Node(e, head); // create and link a new node
if (size == 0)
tail = head; // special case: new node becomes tail also
size++;
}
public void addLast(String e) {
// adds element e to the end of the list
Node newest = new Node(e, null); // node will eventually be the tail
if (isEmpty( ))
head = newest; // special case: previously empty list
else
tail.setNext(newest); // new node after existing tail
tail = newest; // new node becomes the tail
size++;
}
}
My main looks like:
class Main {
public static void main(String[] args) {
System.out.println("Hello world!");
SinglyLinkedList Liste1 = new SinglyLinkedList();
//Bam funktioniert
Liste1.addFirst("Hello world!");
}
}
I would like to add Cursors in the main something like:
Cursor C1 = new addCursor(3);
This C1 Cursor point to list element nr. 3
Cursor C2 = new addCursor(5);
This C2 Cursor points to list element nr.5 ( if exists)
I would like to use cursors in main. So the function addCursor would be in the SinglyLinkedList class but it would return Cursors to Nodes.
So Curser would be like a crab sitting on the node.
Is it possible?
If not maybe other suggestion?
First you can create the Cursor class:
public class Cursor {
private SinglyLinkedList.Node cursor;
Cursor(SinglyLinkedList.Node cursor){
this.cursor = cursor;
}
public SinglyLinkedList.Node getCursor(){
return cursor;
}
}
then the method addCursor in the SinglyLinkedList class:
Cursor addCursor(int value){
int count = 0;
Node tmp = head;
while(tmp != null){
count++;
if(count == value)
return new Cursor(head);
tmp = tmp.next;
}
return null;
}
this method will search in the linked list and return the element in the position equals to value.
Then calling from the main:
public static void main(String[] args) {
System.out.println("Hello world!");
SinglyLinkedList Liste1 = new SinglyLinkedList();
//Bam funktioniert
Liste1.addFirst("Hello world!");
Cursor C1 = Liste1.addCursor(3);
.....
}
I'm trying to make a generic stack and queue class that uses the generic node class. It has empty(), pop(), peek(), push(), and a search() method. I know there is a built-in Stack class and stack search method but we have to make it by using the Node class.
I am unsure of how to make the search method. The search method is supposed to return the distance from the top of the stack of the occurrence that is nearest the top of the stack. The topmost item is considered to be at distance 1; the next item is at distance 2; etc.
My classes are below:
import java.io.*;
import java.util.*;
public class MyStack<E> implements StackInterface<E>
{
private Node<E> head;
private int nodeCount;
public static void main(String args[]) {
}
public E peek() {
return this.head.getData();
}
public E pop() {
E item;
item = head.getData();
head = head.getNext();
nodeCount--;
return item;
}
public boolean empty() {
if (head==null) {
return true;
} else {
return false;
}
}
public void push(E data) {
Node<E> head = new Node<E>(data);
nodeCount++;
}
public int search(Object o) {
// todo
}
}
public class Node<E>
{
E data;
Node<E> next;
// getters and setters
public Node(E data)
{
this.data = data;
this.next = null;
}
public E getData() {
return data;
}
public void setData(E data) {
this.data = data;
}
public Node<E> getNext() {
return next;
}
public void setNext(Node<E> next) {
this.next = next;
}
}
public class MyQueue<E> implements QueueInterface<E>
{
private Node<E> head;
private int nodeCount;
Node<E> rear;
public MyQueue()
{
this.head = this.rear = null;
}
public void add(E item){
Node<E> temp = new Node<E>(item);
if (this.rear == null) {
this.head = this.rear = temp;
return;
}
this.rear.next = temp;
this.rear = temp;
}
public E peek(){
return this.head.getData();
}
public E remove(){
E element = head.getData();
Node<E> temp = this.head;
this.head = this.head.getNext();
nodeCount--;
return element;
}
}
After working on it based off of the first comment I have this:
public int search(Object o){
int count=0;
Node<E> current = new Node<E> (head.getData());
while(current.getData() != o){
current.getNext();
count++;
}
return count;
}
It doesn't have any errors but I cannot tell if it is actually working correctly. Does this seem correct?
It needs the following improvements,
search method should have parameter of type 'E'. So, the signature should look like public int search(E element)
start the count with 1 instead of 0.As you have mentioned topmost item is considered to be at distance 1
initialize current with head, because creating a new node with data value of head(new node(head.getData())) will create an independent node with data same as head node; and the while will run only for the head node as current.getNext() will be null always. Node<E> current = head will create another reference variable pointing to the head.
Instead of != in condition, use if( !current.getData().equals(element.getData())) )
If using your own class as data type, don't forget to override equals method.
Change current.getNext(); to current = current.getNext();
You have problems with other method. Pay attention on top == null. To calculate search() all you need is just iterate over the elements and find position of required value:
public class MyStack<E> {
private Node<E> top;
private int size;
public void push(E val) {
Node<E> node = new Node<>(val);
node.next = top;
top = node;
size++;
}
public E element() {
return top == null ? null : top.val;
}
public E pop() {
if (top == null)
return null;
E val = top.val;
top = top.next;
size--;
return val;
}
public boolean empty() {
return size == 0;
}
public int search(E val) {
int res = 1;
Node<E> node = top;
while (node != null && node.val != val) {
node = node.next;
res++;
}
return node == null ? -1 : res;
}
private static final class Node<E> {
private final E val;
private Node<E> next;
public Node(E val) {
this.val = val;
}
}
}
I assume your MyStack class should be compatible with the Stack class provided by Java as you mention it in your question. This means that your signature public int search(Object o) matches the signature of java.util.Stack#search (apart from synchronised).
To implement the search method using your Node class, we need to traverse the stack and return the index of the first (uppermost) match. First, assign head to a local variable (current). Then you can create a loop where you current.getNext() at the end to get the next element. Stop if the next element is null as we have reached the end of the stack. In the loop, you either count up the index or return this index when the current element's data matches the argument o.
The evaluation needs to be able to deal with null values for your argument o. Therefore, you need to check for null first and adjust your logic accordingly. When o is null, do a null-check against current.getData(). If o is not null, check if current.getData() is equal to o with equals().
Here is a working example: (compatible with java.util.Stack#search)
public int search(Object o) {
int index = 1;
Node<E> current = head;
while (current != null) {
if (o == null) {
if (current.getData() == null) {
return index;
}
} else {
if (o.equals(current.getData())) {
return index;
}
}
current = current.getNext();
index++;
}
return -1; // nothing found
}
To test this, you can write a simple unit test with JUnit like this:
#Test
public void testMyStackSearch() {
// initialize
final MyStack<String> stack = new MyStack<>();
stack.push("e5");
stack.push("e4");
stack.push(null);
stack.push("e2");
stack.push("e1");
// test (explicitly creating a new String instance)
assertEquals(5, stack.search(new String("e5")));
assertEquals(3, stack.search(null));
assertEquals(2, stack.search(new String("e2")));
assertEquals(1, stack.search(new String("e1")));
assertEquals(-1, stack.search("X"));
}
Since you have already a reference implementation, you can replace MyStack with Stack (java.util.Stack) and see if your asserts are correct. If this runs successfully, change it back to MyStack and see if your implementation is correct.
Note: I do not recommend to actually use the Stack implementation in Java. Here, it just serves as a reference implementation for the java.util.Stack#search method. The Deque interface and its implementations offer a more complete and consistent set of LIFO stack operations, which should be used in preference to Stack.
Can someone explain me why the childern node of the nextNode are deleted after clearing the cache.clear(); if I set the the cache conetent arrayList by invoking:
child1.setNext(cache);
and they are not being deleted if I adding them with the for loop child1.next.add(cacheNode);
for (TrieNode cacheNode : cache) {
child1.next.add(cacheNode);
}
The work below works but I just want to understand Why can not I use child1.setNext(cache);?
Code:
ArrayList<TrieNode> cache = new ArrayList<TrieNode>();
if (nextNode.getNext() != null
&& !nextNode.getNext().isEmpty()) {
for (TrieNode nextNodeChildern : nextNode.getNext()) {
cache.add(nextNodeChildern);
}
nextNode.setEdge(communsubString);
nextNode.getNext().clear();
TrieNode child1 = new TrieNode(substringSplit1);
//child1.setNext(cache);
for (TrieNode cacheNode : cache) {
child1.next.add(cacheNode);
}
nextNode.next.add(child1);
cache.clear();
TrieNode child2 = new TrieNode(substringSplit2);
child2.setWord(true);
nextNode.next.add(child2);
}
TrieNode class:
class TrieNode {
ArrayList<TrieNode> next = new ArrayList<TrieNode>();
String edge;
boolean isWord;
// To create normal node.
TrieNode(String edge) {
this.edge = edge;
}
// To create the root node.
TrieNode() {
this.edge = "";
}
public ArrayList<TrieNode> getNext() {
return next;
}
public void setNext(ArrayList<TrieNode> next) {
this.next = next;
}
public String getEdge() {
return edge;
}
public void setEdge(String edge) {
this.edge = edge;
}
public boolean isWord() {
return isWord;
}
public void setWord(boolean isWord) {
this.isWord = isWord;
}
}
When you pass cache to setNext you're passing a reference to the cache list, i.e. the List in your node and the List in your main code points to the same List in memory. When you call clear you're emptying out that list, which is being used by your node.
You need to use a copy of the list for your node by either taking a copy outside or inside the node class, so something like this would work:
public void setNext(ArrayList<TrieNode> next) {
this.next = new ArrayList<>(next);
}
This will create a new ArrayList inside the node and copy all the elements from next into it.
Right now I am trying to create a circular list, where when I use hasNext() from an Iterator it should always return true. However right now it is returning that it is not a circular list, and I am also having problems printing out the values (in this example Strings) of the ArrayList. Here is the CircularList class I created, which has a inner Node class for the objects that are put into the list:
public class CircularList<E> implements Iterable{
private Node<E> first = null;
private Node<E> last = null;
private Node<E> temp;
private int size = 0;
//inner node class
private static class Node<E>{ //In this case I am using String nodes
private E data; //matching the example in the book, this is the data of the node
private Node<E> next = null; //next value
//Node constructors, also since in this case this is a circular linked list there should be no null values for previous and next
private Node(E data){
this.data = data;
}
}
//end of inner node class
public void addValue(E item){
Node<E> n = new Node<E>(item);
if(emptyList() == true){ //if the list is empty
//only one value in the list
first = n;
last = n;
}
else{ //if the list has at least one value already
//store the old first value
temp = first;
//the new first is the input value
first = n;
//next value after first is the old first value
first.next = temp;
//if after this there will be only two values in the list once it is done
if(size == 1){
last = temp;
}
//if the list is greater than one than the last value does not change, since any other values will be put before last in this case, and not replace it
//creating the circular part of the list
last.next = first;
}
size++;
}
public boolean emptyList(){
boolean result = false;
if(first == null && last == null){ //if there is no values at all
result = true;
}
return result;
}
#Override
public Iterator<E> iterator() {
// TODO Auto-generated method stub
return new CircularIterator<E>(); //each time this method is called it will be creating a new instance of my Iterator
}
}
Here is the Iterator class I am making:
public class CircularIterator<E> implements Iterator<E> {
#Override
public boolean hasNext() {
return false;
}
#Override
public E next() {
// TODO Auto-generated method stub
return null;
}
#Override
public void remove() {
// TODO Auto-generated method stub
}
}
and finally the Test class:
public class Test {
static CircularList<String> c = new CircularList<String>(); //in this case it is a string list
static Iterator it = c.iterator();
public static void main(String[]args){
c.addValue("Bob");
c.addValue("Joe");
c.addValue("Jaina");
c.addValue("Hannah");
c.addValue("Kelly");
Iterate();
for(String val : c){
System.out.println(val);
}
}
private static boolean Iterate(){
boolean result = false;
if(!it.hasNext()){
System.out.println("Not a circular list!");
}
else{
result = true;
}
return result;
}
}
Again I am trying to get it to always return true, I think the problem lies with my hasNext() method, but I am not completely sure.
The main problem with your approach is you are using static inner classes - this is not necessary. Making the outer class generic is sufficient. The generic parameter is then inherited by the inner classes and all sorts of issues disappear.
Implementing an Iterator properly is subtle.
public static class CircularList<E> implements Iterable<E> {
private Node first = null;
private Node last = null;
private int size = 0;
private class Node {
private E data;
private Node next = null;
private Node(E data) {
this.data = data;
}
}
public void addValue(E item) {
Node n = new Node(item);
if (emptyList()) {
//only one value in the list
first = n;
last = n;
} else { //if the list has at least one value already
//store the old first value
Node temp = first;
//the new first is the input value
first = n;
//next value after first is the old first value
first.next = temp;
//if after this there will be only two values in the list once it is done
if (size == 1) {
last = temp;
}
//if the list is greater than one than the last value does not change, since any other values will be put before last in this case, and not replace it
//creating the circular part of the list
last.next = first;
}
size++;
}
public boolean emptyList() {
boolean result = false;
if (first == null && last == null) { //if there is no values at all
result = true;
}
return result;
}
#Override
public Iterator<E> iterator() {
return new CircularIterator(); //each time this method is called it will be creating a new instance of my Iterator
}
private class CircularIterator implements Iterator<E> {
// Start at first.
Node next = first;
public CircularIterator() {
}
#Override
public boolean hasNext() {
// Stop when back to first.
return next != null;
}
#Override
public E next() {
if (hasNext()) {
E n = next.data;
next = next.next;
if (next == first) {
// We're done.
next = null;
}
return n;
} else {
throw new NoSuchElementException("next called after end of iteration.");
}
}
}
}
public void test() {
CircularList<String> c = new CircularList<>();
c.addValue("A");
c.addValue("B");
c.addValue("C");
c.addValue("D");
for (String s : c) {
System.out.println(s);
}
}
Your main code was essentially correct - all I did was remove the unnecessary generics parameters from the inner classes.
Note that the way you add node to the list means that the items come out backwards. You could adjust that in your addValue method quite easily.
You can simply use following for circular iteration. This Circular list behave as same as other java.util.Lists. But it's iteration is modified. You don't need to care about it's performance tuning additionally. Because it's super class (LinkedList) is already well tested and enough stronger to use.
`public class CircularList extends LinkedList {
#Override
public Iterator<E> iterator() {
return createIterator();
}
//create new iterator for circular process
private Iterator<E> createIterator() {
return new Iterator<E>() {
private int index = 0;
#Override
public boolean hasNext() {
//no elements when list is empty
return isEmpty();
}
#Override
public E next() {
E node = get(index);
//rotate index
index++;
if (index == size()) {
index = 0;
}
return node;
}
};
}
}`
My first assignment in my programming class is about writing code for a Doubly Linked List, which includes writing an add, remove, size, iterator first, iterator last, and iterator find functions. I have spent 3 hours and gotten no where in understanding this. I understand what happens if I can see it in a picture. But my problem is translating it to code. This is what I have so far:
public class DoublyLinkedList< G > {
public class node {
G data;
node next;
node prev;
public node(G data, node next, node prev) {
this.data = data;
this.next = next;
this.prev = prev;
}
}
node header;
node footer;
public DoublyLinkedList() {
header = new node(null, null, null);
footer = new node(null, header, null);
header.next = footer;
}
public void add(G data) {
header.next = new node(data, footer.prev, footer);
}
public int size() {
node current = header.next;
int quanity = 0;
if (current == null) {
return 0;
}
while (current != null) {
current = current.next;
quanity++;
}
return quanity;
}
public static void main(String args[]) {
DoublyLinkedList<Integer> test = new DoublyLinkedList<Integer>();
//test.add(new Integer(2));
//test.add(new Integer(22));
//test.add(new Integer(222));
System.out.println(test.size());
}
}
As you can see, I've been using the main() to test everything. From what I've been told by my teacher, my constructor and node class look fine. However I know either my add and size are not right because when I test this, when there is no nodes in the list, it displays nothing, but it should display 0 right? I mean, assuming my size code is right, which I'm not sure of.
And whenever I add a node, no matter how many I add, it always displays 1. So either both add and size are broken, or both are. I have not written the other functions as it makes no sense until I figure these ones out. Please someone help me understand this! Thank you.
Declare a size field in DoublyLinkedList to store the current size of the list. When add succeed, make size++. When remove succeed, make size--. And size() method just simply return the value of size.
The sample code is here:
private int size = 0;
public void add(G data) {
header.next = new node(data, footer.prev, footer);
size++;
}
public int size() {
return size;
}
Noticed couple of things:
First, footer is not constructed correctly. It should be:
public DoublyLinkedList() {
..
footer = new node(null, null, header);
// your code is incorrectly creating a circular list
..
}
Secondly add() method doesn't look correct. It should be something like :
public void add(G data) {
Node newNode = new Node(data, header, null);
header.prev = newNode
header = newNode;
}
// for adding at the front (LIFO)
OR
public void add(G data) {
Node newNode = new Node(data, null, footer);
footer.next = newNode
footer = newNode;
}
//for adding at the tail (FIFO)
Check out the wikipedia entry for doubly linked lists. It has some good pseudo code.
Using your own code I'm going to make a few suggestions
public class DoublyLinkedList< G > {
public class node {
G data;
node next;
node prev;
public node(G data) {
this.data = data;
this.next = null;
this.prev = null;
}
}
node header;
node footer;
public DoublyLinkedList() {
header = new node(null);
footer = new node(null);
header.next = footer;//link the header to the footer
footer.prev = header;//link the footer to the header
}
public void add(G data) { //assuming you are adding the node to the head of the list
node newNode = new node(data); //creating new node to add with the data
newNode.next = header.next; // setting new node to head of the list or the footer
newNode.prev = header; //setting the new node's previous node to the header
header.next = newNode; //setting the newNode as the next node.
}
public int size() {
node current = header.next;
int quantity = 0;
if (current.data == null/*Empty list*/) { //you needed to specify what you were trying to test
return 0;
}
while (current.data != null/*traversing the list*/) {
current = current.next;
quantity++;
}
return quantity;
}
public static void main(String args[]) {
DoublyLinkedList<Integer> test = new DoublyLinkedList<Integer>();
//test.add(new Integer(2));
//test.add(new Integer(22));
//test.add(new Integer(222));
System.out.println(test.size());
}
}
Here you go:
public class DoublyLinkedList {
private class Node {
String value;
Node next,prev;
public Node(String val, Node n, Node p) {
value = val;
next = n;
prev=p;
}
Node(String val) {
this(val, null, null);
}
}
private Node first;
private Node last;
public DoublyLinkedList() {
first = null;
last = null;
}
public boolean isEmpty(){
return first==null;
}
public int size(){
int count=0;
Node p=first;
while(p!=null){
count++;
p=p.next;
}
return count;
}
public void add(String e) {
if(isEmpty()){
last=new Node(e);
first=last;
}
else{
last.next=new Node(e, null, last);
last=last.next;
}
}
public void add(int index, String e){
if(index<0||index>size()){
String message=String.valueOf(index);
throw new IndexOutOfBoundsException(message);
}
if(index==0){
Node p=first;
first=new Node(e,p,null);
if(p!=null)
p.prev=first;
if(last==null)
last=first;
return;
}
Node pred=first;
for(int k=1; k<=index-1;k++){
pred=pred.next;
}
Node succ=pred.next;
Node middle=new Node(e,succ,pred);
pred.next=middle;
if(succ==null)
last=middle;
else
succ.prev=middle;
}
public String toString(){
StringBuilder strBuilder=new StringBuilder();
Node p=first;
while(p!=null){
strBuilder.append(p.value+"\n");
p=p.next;
}
return strBuilder.toString();
}
public String remove(int index){
if(index<0||index>=size()){
String message=String.valueOf(index);
throw new IndexOutOfBoundsException(message);
}
Node target=first;
for(int k=1; k<=index;k++){
target=target.next;
}
String element=target.value;
Node pred=target.prev;
Node succ=target.next;
if(pred==null)
first=succ;
else
pred.next=succ;
if(succ==null)
last=pred;
else
succ.prev=pred;
return element;
}
public boolean remove(String element){
if(isEmpty())
return false;
Node target=first;
while(target!=null&&!element.equals(target.value))
target=target.next;
if(target==null)
return false;
Node pred=target.prev;
Node succ=target.next;
if(pred==null)
first=succ;
else
pred.next=succ;
if(succ==null)
last=pred;
else
succ.prev=pred;
return true;
}
public static void main(String[] args){
DoublyLinkedList list1=new DoublyLinkedList();
String[] array={"a","c","e","f"};
for(int i=0; i<array.length; i++){
list1.add(array[i]);
}
list1.add(1,"b");
list1.add(3,"d");
System.out.println(list1);
}
}