If you look at my toString() method below, you can see that I have not finished it. I don't know how? Can anyone explain how I might proceed? Confused :-| I'm new to linked lists and so I automatically went for the Arrays.toString() approach before I realized that there is, of course, no arrays anywhere.
import java.util.Arrays;
public class LinkedIntegerStack {
private Node top = null;
private int size = 0;
public int size(){
return size;
}
public boolean isEmpty() {
if(top == null){
return true;
}
else{
return false;
}
}
public void push(int value) {
Node n = new Node(value);
n.next = top;
top = n;
size++;
}
public int top(){ //just returns a value..doesn't change structure
return top.element;
}
public int pop(){
if (isEmpty()){
throw new StackEmptyException();
}
int toReturn = top.element;
top = top.next;
size--;
return toReturn;
}
public String toString() {
return "[ Top = " + size +"]" + "[Stack = " );
}
private class Node {
int element;
Node next;
public Node(int value){
element = value;
}
}
public static void main(String[] args) throws StackEmptyException{
LinkedIntegerStack stack = new LinkedIntegerStack();
stack.push(17);
System.out.println(stack);
stack.push(11);
System.out.println(stack);
try{
stack.pop();
System.out.println(stack);
}
catch(StackEmptyException ex){
System.out.print("Stack is Empty: Error");
}
System.out.println("Stack: " + stack);
}
}
The solution is pretty easy.
It should be enough to iterate through the stack.
public String toString() {
String result = "[ Top = " + size +"]" + "[Stack = [";
if (top == null) {
return result + "]]";
Node temp = top;
while (temp != null) {
result += temp + ', '
temp = temp.next;
}
return result += temp.element + "]]";
}
Of course you should add at least getter methods to Node class, i.e. getElement() and getNext();
PS: the code isn't tested, but it should be fine.
System.out.println(Arrays.toString(stack.toArray()));
From https://stackoverflow.com/a/395403/2736496
JavaDoc: Arrays.toString(o[]), Collection.toArray(cll)
Related
I need to navigate my 23Tree and print all the levels and corresponding elements. However, my recursion goes in any one direction and does not return and perform other calls. Any help would be much appreciated.
Here is my node class:
class Node<T extends Comparable<T>> {
List<T> vals = new ArrayList<T>();
List<Node<T>> children = new ArrayList<Node<T>>();
boolean isLeaf() { return children.size() == 0; }
boolean is4Node() { return vals.size() == 3; }
// new Nodes always are 2-nodes (1 value). The node may be
// a leaf, or has 2 children.
Node(T x) {
vals.add(x);
}
Node(T x, Node<T> left, Node<T> right) {
vals.add(x);
children.add(left);
children.add(right);
children.add(null); // hack
}
This is my recursive function to print the nodes:
private boolean iterateChildrenAndPrintPerLevelAndLevelType(int level, String levelType, Node root){
System.out.println("present element: " + root);
if(root.vals.size() == 1 ){
System.out.println("Level = " + level + " [" + levelType + "] value = " + root.vals.get(0));
}else if(root.vals.size() == 2 ){
System.out.println("Level = " + level + " [" + levelType + "] value = " + root.vals.get(0) + "/" + root.vals.get(1));
}
if(root.children.get(0) != null){
iterateChildrenAndPrintPerLevelAndLevelType(level+1, "left", (Node) root.children.get(0));
}
if(root.children.get(1) != null){
iterateChildrenAndPrintPerLevelAndLevelType(level+1, "middle", (Node) root.children.get(1));
}
if(root.children.get(2) != null){
iterateChildrenAndPrintPerLevelAndLevelType(level+1, "right", (Node) root.children.get(2));
}
return true;
}
And here is the output:
present element: [[[a]b[c]]d, [[e]f[g]]h[[i]j, [k]y[z]]]
Level = 0 [root] value = d/h
present element: [[a]b[c]]
Level = 1 [left] value = b
present element: [a]
Level = 2 [left] value = a
(Edit) Here is my main method:
public static void main(String[] args) {
StringTwoThreeTree set = new StringTwoThreeTree();
try{
String line = null;
FileReader fileReader =
new FileReader("C:\\Users\\Redoubt\\IdeaProjects\\23Tree\\src\\resources\\test.dat");
// new FileReader("C:\\Users\\Redoubt\\IdeaProjects\\23Tree\\src\\resources\\a4q1search.txt");
// Always wrap FileReader in BufferedReader.
BufferedReader bufferedReader =
new BufferedReader(fileReader);
while((line = bufferedReader.readLine()) != null) {
set.insert(line);
}
// System.out.println("\n\n\n");
String str = set.toString();
// System.out.println(str);
set.print();
}catch (Exception e){
}
}
and the contents of the file test.dat :
a
a
b
c
d
e
f
g
h
i
j
k
y
z
Just for clarity, I'm adding the 2 large classes as well:
StringTwoThree class:
import java.util.List;
public class StringTwoThreeTree extends TwoThreeTree<String> {
#Override
public String toString() {
return super.toString();
}
public void insert(String str){
super.add(str);
}
public void print(){
Node root = super.root;
// System.out.println(root.vals);
// dumpList("",root);
iterateChildrenAndPrintPerLevelAndLevelType(0, "root", root);
super.displayLevelWise();
}
private void dumpList(String string, Node list) {
int i = 0;
for (Object item : list.children) {
if (item instanceof List) {
dumpList(string + i, (Node) item);
} else {
System.out.println(String.format("%s%d %s", string, i, item));
}
++i;
}
}
private boolean iterateChildrenAndPrintPerLevelAndLevelType(int level, String levelType, Node root){
System.out.println("present element: " + root);
if(root.vals.size() == 1 ){
System.out.println("Level = " + level + " [" + levelType + "] value = " + root.vals.get(0));
}else if(root.vals.size() == 2 ){
System.out.println("Level = " + level + " [" + levelType + "] value = " + root.vals.get(0) + "/" + root.vals.get(1));
}
if(root.children.get(0) != null){
iterateChildrenAndPrintPerLevelAndLevelType(level+1, "left", (Node) root.children.get(0));
}
if(root.children.get(1) != null){
iterateChildrenAndPrintPerLevelAndLevelType(level+1, "middle", (Node) root.children.get(1));
}
if(root.children.get(2) != null){
iterateChildrenAndPrintPerLevelAndLevelType(level+1, "right", (Node) root.children.get(2));
}
return true;
}
}
TwoThreeTree class:
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Queue;
public class TwoThreeTree<T extends Comparable<T>> implements Iterable<T> {
// a Node has 1 (2-Node) or 2 (3-Node) values
// and 2 or 3 children. Values and children are stored
// in ArrayLists. If there are children, that ArrayList
// has a null element at the end, so as to make easier the
// method which adds a new child.
class Node<T extends Comparable<T>> {
List<T> vals = new ArrayList<T>();
List<Node<T>> children = new ArrayList<Node<T>>();
boolean isLeaf() { return children.size() == 0; }
boolean is4Node() { return vals.size() == 3; }
// new Nodes always are 2-nodes (1 value). The node may be
// a leaf, or has 2 children.
Node(T x) {
vals.add(x);
}
Node(T x, Node<T> left, Node<T> right) {
vals.add(x);
children.add(left);
children.add(right);
children.add(null); // hack
}
public String toString() {
String answer = "[";
for (int i=0; i<vals.size(); i++) {
if (i != 0) answer += ", ";
if (children.size() != 0)
answer += children.get(i).toString();
answer += vals.get(i);
}
if (children.size() != 0)
answer += children.get(children.size()-2).toString();
return answer + "]";
}
// used in Iterator
void getVals(List<T> iteratorList) {
for (int i=0; i<vals.size(); i++) {
if (children.size() != 0)
children.get(i).getVals(iteratorList);
iteratorList.add(vals.get(i));
}
if (children.size() != 0)
children.get(children.size()-2).getVals(iteratorList);
}
// recursively adds a new value to a subtree
boolean add(T val) {
if (isLeaf())
return addToLeaf(val);
else return addToInterior(val);
}
// new values are always added to a leaf. The result may be a 4-node leaf.
boolean addToLeaf(T x) {
int cmp;
// size is 1 for a 2-node, or 2 for a 3-node
for (int i = 0; i < vals.size(); i++) {
cmp = x.compareTo(vals.get(i));
if (cmp == 0) return false;
else if (cmp < 0) {
vals.add(i,x);
return true;
}
}
vals.add(x);
return true;
}
// adds a value to a subtree rooted by an interior node. If
// the addition results in one of the children being a 4-node,
// then adjustments are made.
boolean addToInterior(T x) {
int cmp;
// size is 1 for a 2-node, or 2 for a 3-node
for (int i = 0; i <= vals.size(); i++) {
if (i == vals.size()) cmp = -1; // hack because there is no vals[2]
else cmp = x.compareTo(vals.get(i));
if (cmp == 0) return false;
else if (cmp < 0) {
boolean retVal = children.get(i).add(x);
if (children.get(i).is4Node())
childIs4Node(i);
return retVal;
}
}
return false; // unreachable -- just for compiler
}
// the ith child is a 4-node
void childIs4Node(int i) {
Node<T> the4Node = children.get(i);
// move the middle value from the 4-node child up
// to its parent
if (i == 2)
vals.add(children.get(i).vals.get(1));
else vals.add(i, children.get(i).vals.get(1));
Node<T> newChild1, newChild2;
if (children.get(i).isLeaf()) {
newChild1 = new Node<T>(children.get(i).vals.get(0));
newChild2 = new Node<T>(children.get(i).vals.get(2));
}
else {
newChild1 = new Node<T>(children.get(i).vals.get(0),
children.get(i).children.get(0),
children.get(i).children.get(1));
newChild2 = new Node<T>(children.get(i).vals.get(2),
children.get(i).children.get(2),
children.get(i).children.get(3));
}
children.remove(the4Node);
children.add(i, newChild2);
children.add(i, newChild1);
}
}
Node<T> root;
public TwoThreeTree() {
root = null;
}
// TwoThreeTree add
public boolean add(T val) {
if (root == null) {
root = new Node<T>(val);
return true;
}
else {
boolean isNew = root.add(val);
// if root is a 4-node, split it
if (root.vals.size() == 3) {
Node<T> left, right;
if (root.isLeaf()) {
left = new Node<T>(root.vals.get(0));
right = new Node<T>(root.vals.get(2));
}
else {
left = new Node<T>(root.vals.get(0),
root.children.get(0),
root.children.get(1));
right = new Node<T>(root.vals.get(2),
root.children.get(2),
root.children.get(3));
}
root = new Node<T>(root.vals.get(1), left, right);
}
return isNew;
}
}
// this method creates a list containing all of the values in
// the tree and returns that list's iterator
public Iterator<T> iterator() {
List<T> vals = new ArrayList<T>();
if (root != null) root.getVals(vals);
return vals.iterator();
}
public String toString(){
String result = "[";
for (T item : this
) {
result += item.toString() + ",";
}
result = result.substring(0,result.length()-1);
result += "]";
return result;
}
public void displayLevelWise(){
}
}
Your index is going out of bound in your private boolean iterateChildrenAndPrintPerLevelAndLevelType(int level, String levelType, Node root) method.
I am trying to add two non negative numbers, the digits of which are stored in reverse order in two separate linked lists. The answer should also be a linked list with digits reversed and no trailing zeros.
I understand that there is a way to solve this question by adding digits and maintaining a carry each time, but I am trying to solve it by using addition operation on numbers.
Here's my code:
/**
* Definition for singly-linked list.
* class ListNode {
* public int val;
* public ListNode next;
* ListNode(int x) { val = x; next = null; }
* }
*/
public class Solution {
public ListNode addTwoNumbers(ListNode a, ListNode b) {
if(a==null || b==null){
return null;
}
String num1 = "";
String num2 = "";
ListNode temp1 = a;
ListNode temp2 = b;
while(temp1!=null){
num1 = num1+Integer.toString(temp1.val);
temp1 = temp1.next;
}
new StringBuilder(num1).reverse().toString();
double value1 = Double.parseDouble(num1);
while(temp2!=null){
num2 = num2+Integer.toString(temp2.val);
temp2 = temp2.next;
}
new StringBuilder(num2).reverse().toString();
double value2 = Double.parseDouble(num2);
double result = value1+value2;
String res = String.format("%.0f",result);
ListNode first_node = new ListNode(Character.getNumericValue(res.charAt(0)));
ListNode ans = first_node;
for(int j=1;j<res.length();j++){
ListNode node = new ListNode(Character.getNumericValue(res.charAt(j)));
add(node,ans);
}
return ans;
}
public void add(ListNode node, ListNode ans){
ListNode temp;
temp = ans;
ans = node;
ans.next = temp;
}
}
My code has been giving wrong answers. Can anyone point out the errors?
Your approach is not correct and indirect.
You are trying to do big numbers arithmetics using floating point operations.
As a result - computing errors.
We have:
List<Integer> firstNumber;
List<Integer> secondNumber;
Lets assume firstNumber > secondNumber.
Try this alogrithm:
List<Integer> result = new ArrayList<>();
int i = 0;
int appendix = 0;
for (; i < secondNumber.size(); i++) {
int sum = firstNumber.get(i) + secondNumber.get(i) + appendix;
result.append(sum % 10);
appendix = sum / 10;
}
for (; i < firstNumber.size(); i++) {
int sum = firstNumber.get(i) + appendix;
result.append(sum % 10);
appendix = sum / 10;
}
if (appendix != 0)
result.append(appendix);
return result;
Your add function looks incorrect. You will get you number in the reverse order than what is expected.
Also, your solution is missing the point of the question. Your approach will fail if you have a number with a lot of digits (even double has its limits ~ 2^1024 I think). A linked list representation allows for numbers even bigger.
The correct solution would just iterate through both the lists simultaneously with a carry digit while creating the solution list. If this is a question in an assignment or coding competition, your solution would be judged wrong.
Your add method is wrong, it doesn't build correctly the list. Here is how the final part of your method should look, without the add method:
for(int j=1;j<res.length();j++){
ans.next = new ListNode(Character.getNumericValue(res.charAt(j)));;
ans = ans.next;
}
return first_node;
In your approach, the variable ans is not updating. You can try this:
ans = add(node,ans);
and in your add method, change the method to return ListNode ans
Your approach is not straightforward and wouldn't give you expected results.
Here is a simple approach which wouldn't require much explanation as the addition is simple integer by integer.
Do note that i carry forward when the sum of two integers is greater than 9 else continue with the sum of next integers from both the list.
class Node {
private Object data;
private Node 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; }
public Node(final Object data, final Node next) {
this.data = data;
this.next = next;
}
#Override
public String toString() { return "Node:[Data=" + data + "]"; }
}
class SinglyLinkedList {
Node start;
public SinglyLinkedList() { start = null; }
public void addFront(final Object data) {
// create a reference to the start node with new data
Node node = new Node(data, start);
// assign our start to a new node
start = node;
}
public void addRear(final Object data) {
Node node = new Node(data, null);
Node current = start;
if (current != null) {
while (current.getNext() != null) {
current = current.getNext();
}
current.setNext(node);
} else {
addFront(data);
}
}
public void deleteNode(final Object data) {
Node previous = start;
if (previous == null) {
return;
}
Node current = previous.getNext();
if (previous != null && previous.getData().equals(data)) {
start = previous.getNext();
previous = current;
current = previous.getNext();
return;
}
while (current != null) {
if (current.getData().equals(data)) {
previous.setNext(current.getNext());
current = previous.getNext();
} else {
previous = previous.getNext();
current = previous.getNext();
}
}
}
public Object getFront() {
if (start != null) {
return start.getData();
} else {
return null;
}
}
public void print() {
Node current = start;
if (current == null) {
System.out.println("SingleLinkedList is Empty");
}
while (current != null) {
System.out.print(current);
current = current.getNext();
if (current != null) {
System.out.print(", ");
}
}
}
public int size() {
int size = 0;
Node current = start;
while (current != null) {
current = current.getNext();
size++;
}
return size;
}
public Node getStart() {
return this.start;
}
public Node getRear() {
Node current = start;
Node previous = current;
while (current != null) {
previous = current;
current = current.getNext();
}
return previous;
}
}
public class AddNumbersInSinglyLinkedList {
public static void main(String[] args) {
SinglyLinkedList listOne = new SinglyLinkedList();
SinglyLinkedList listTwo = new SinglyLinkedList();
listOne.addFront(5);
listOne.addFront(1);
listOne.addFront(3);
listOne.print();
System.out.println();
listTwo.addFront(2);
listTwo.addFront(9);
listTwo.addFront(5);
listTwo.print();
SinglyLinkedList listThree = add(listOne, listTwo);
System.out.println();
listThree.print();
}
private static SinglyLinkedList add(SinglyLinkedList listOne, SinglyLinkedList listTwo) {
SinglyLinkedList result = new SinglyLinkedList();
Node startOne = listOne.getStart();
Node startTwo = listTwo.getStart();
int carry = 0;
while (startOne != null || startTwo != null) {
int one = 0;
int two = 0;
if (startOne != null) {
one = (Integer) startOne.getData();
startOne = startOne.getNext();
}
if (startTwo != null) {
two = (Integer) startTwo.getData();
startTwo = startTwo.getNext();
}
int sum = carry + one + two;
carry = 0;
if (sum > 9) {
carry = sum / 10;
result.addRear(sum % 10);
} else {
result.addRear(sum);
}
}
return result;
}
}
Sample Run
Node:[Data=3], Node:[Data=1], Node:[Data=5]
Node:[Data=5], Node:[Data=9], Node:[Data=2]
Node:[Data=8], Node:[Data=0], Node:[Data=8]
I have posted this code several times I apologize if you keep looking at this question. I've been working on this for a bit so any help would be helpful i've done as much as I can so far. But when my program prints the data it switches the 8 and the 7 around and I can't figure out why! Here is all the code. And I have not started making my remove method yet so disregard that functionality.
public class MyLinkedList<AnyType> implements Iterable<AnyType> {
private int theSize;
private Node<AnyType> beginMarker;
private Node<AnyType> endMarker;
public class Node<AnyType> {
public Node(AnyType data, Node<AnyType> head, Node<AnyType> tail) {
myData = data;
myHead = head;
myTail = tail;
}
public AnyType myData;
public Node<AnyType> myHead;
public Node<AnyType> myTail;
}
public MyLinkedList() {
beginMarker = new Node(null, endMarker, null);
endMarker = new Node(null, null, beginMarker);
theSize = 0;
}
public void clear() {
beginMarker.myHead = endMarker;
endMarker.myTail = beginMarker;
}
public int size() {
return theSize;
}
public boolean exist(AnyType newVal) {
beginMarker.myHead.myData = newVal;
if (newVal != null) {
return true;
}
return false;
}
private void addBefore(Node<AnyType> previousNode, AnyType newNode) {
Node<AnyType> new_node = new Node<>(newNode, previousNode.myTail, previousNode);
new_node.myTail.myHead = new_node;
previousNode.myTail = new_node;
theSize++;
}
public boolean add(AnyType newVal) {
{
add(size(), newVal);
return true;
}
}
public boolean add(int index, AnyType newVal) {
addBefore(getNode(index, 0, size()), newVal);
return true;
}
private Node<AnyType> getNode(int index) {
return getNode(index, 0, size() - 1);
}
public Node<AnyType> get(AnyType nodeData) {
Node<AnyType> node = beginMarker;
while (node != endMarker) {
// Means node.data = nodeData
if (node.myData.equals(nodeData)) {
return node;
}
}
return null;
}
// Added method
private Node<AnyType> getNode(int index, int lower, int upper) {
Node<AnyType> x;
if (index < lower || index > upper)
throw new IndexOutOfBoundsException();
if (index < size() / 2) {
x = beginMarker.myHead;
for (int i = 0; i < index; i++)
x = x.myHead;
} else {
x = endMarker.myTail;
for (int i = size(); i > index; i--) {
x = x.myTail;
}
}
return x;
}
public void printList() {
Node temp = beginMarker.myHead;
while (temp != null) {
System.out.println(temp.myData);
temp = temp.myHead;
}
}
public java.util.Iterator<AnyType> iterator() {
return new LinkedListIterator();
}
public void remove(AnyType removeVal) {
/*
* if(node.myData.equals(nodeData))
*
* MyLinkedList testList = new MyLinkedList();
*
* Node temp = testList.beginMarker.myData; while(temp != null){
*
* if(temp == removeVal){ temp.myTail = temp.myHead; temp.myHead =
* temp.myTail; } else{ temp.myHead = temp; }
*
*
* }
*/
}
private class LinkedListIterator implements java.util.Iterator<AnyType> {
private Node<AnyType> node_ = beginMarker;
public void remove() {
}
public boolean hasNext() {
if (node_.myHead != null) {
return true;
}
return false;
}
public AnyType next() {
if (!hasNext()) {
return null;
}
node_ = node_.myHead;
return node_.myData;
}
}
private static void testListIntegers() {
MyLinkedList<Integer> testList = new MyLinkedList<Integer>();
testList.add(new Integer(5));
testList.add(new Integer(4));
testList.add(new Integer(3));
System.out.println(" We have so far inserted " + testList.size() + " elements in the list");
testList.remove(4);
System.out.println(" Now, there is only " + testList.size() + " elements left in the list");
testList.add(1, new Integer(7));
testList.add(2, new Integer(8));
System.out.println(" About to print content of the list");
testList.printList();
}
private static void testListStrings() {
MyLinkedList<String> testList = new MyLinkedList<String>();
testList.add(new String("hello"));
testList.add(new String("this is"));
testList.add(new String("cs3345 project 2"));
System.out.println(" We have so far inserted " + testList.size() + " elements in the list");
testList.remove("this is");
System.out.println(" Now, there is only " + testList.size() + " elements left in the list");
testList.add(1, "a modified version of");
testList.add(2, "cs3345 project 2, call it version 2");
System.out.println(" About to print content of the list");
testList.printList();
}
public static void main(String args[]) throws Exception {
// Add whatever code you need here
// However, you will need to call both testListIntegers()
// and testListStrings()
testListIntegers();
testListStrings();
}
}
The output is as follows:
We have so far inserted 3 elements in the list
Now, there is only 3 elements left in the list
About to print content of the list
8
7
3
4
5
We have so far inserted 3 elements in the list
Now, there is only 3 elements left in the list
About to print content of the list
cs3345 project 2, call it version 2
a modified version of
cs3345 project 2
this is
hello
Problem is with addBefore method:
private void addBefore(Node<AnyType> previousNode, AnyType newNode) {
Node<AnyType> new_node = new Node<>(newNode, previousNode.myTail, previousNode);
new_node.myTail.myHead = new_node;
previousNode.myTail = new_node;
theSize++;
}
It is the same like:
private void addBefore(Node<AnyType> previousNode, AnyType newNode) {
Node<AnyType> new_node = new Node<>(newNode, previousNode.myTail, previousNode);
previousNode.myHead = new_node;
previousNode.myTail = new_node;
theSize++;
}
So basically you are breaking doubly linked list.
Edit:
According to algorithm described here this method should look like:
private void addBefore(Node<AnyType> previousNode, AnyType newNode) {
Node<AnyType> new_node = new Node<>(newNode, previousNode, previousNode.myTail);
if(previousNode.myTail==null){
beginMarker.myHead = new_node;
} else {
previousNode.myTail.myHead = new_node;
}
previousNode.myTail = new_node;
theSize++;
}
See that your list is indexed from 0 so the output should be:
5
7
8
4
3
And next problem is in printList method (infinite loop) because somewhere is wrong usage of your begin/end marker.
adding theSize--; at the end of the remove method should decrease the elements from 3 to 1
I'm trying to sum up items in a node both iteratively and recursively. I already wrote the program to do the iterative way and I'm having problems on how this can be done recursively.
code:
public int sumIterative() {
Node newNode= new Node(item, next);
int sum = 0;
while(newNode != null){
sum = sum + item;
newNode = newNode.next;
}
return sum;
}
My effort on making the recursive way:
public int sumRecursive() {
Node newNode = new Node(item,next);
int sum = 0;
int result;
if(newNode == null){
result = 0;
} else {
return sumRecursive();
}
return sum;
}
I am trying to make this with the logic of "there are no nodes after this"
How is it possible for this to be done recursively?
Edit
This is the public driver method, I can post my whole code on demand
public int sumRecursive() {
int sum = 0;
if (top != null) {
sum = top.sumRecursive();
}
return sum;
}
class LinkedList {
private class Node {
public int item;
public Node next;
public Node(int newItem, Node newNext) {
item = newItem;
next = newNext;
}
public int getItem() {
return item;
}
public Node getNext() {
return next;
}
public void setNext(Node newNext) {
next = newNext;
}
// My Other Node methods
// Recursively add up the numbers stored in this
// and all the nodes after this.
// Base case: there are no nodes after this.
public int sumRecursive() {
Node node = new Node(item,next);
/*Node newNode = new Node(item,next);
int sum = 0;
if (null == newNode) {
return sum;
} else {
sum += sumRecursive(newNode.next);
}*/
if (node == null) {
return node.item;
} else {
return node.item + sumRecursive(node.next);
}
}
// Iteratively add up the numbers stored in this
// and all the nodes after this.
public int sumIterative() {
Node newNode= new Node(item, next);
int sum = 0;
while(newNode != null) {
sum = sum + item;
newNode = newNode.next;
}
return sum;
}
} // end class Node
private Node top; // a pointer to the first node in the list (when it's not empty)
public LinkedList() {
top = null; // empty list
}
// Insert a node at the front of the list
public void insertAtFront(int newItem) {
top = new Node(newItem, top);
}
// Print out the list (10 numbers per line)
public void printList() {
int count = 1;
Node curr;
if (top == null) {
System.out.println( "List is empty" );
} else {
curr = top;
while (curr != null) {
System.out.print( " " + curr.item );
count++;
if (count % 10 == 0) {
System.out.println();
}
curr = curr.next;
}
if (count % 10 != 0) {
System.out.println();
}
}
}
// public driver method for sumRecursive
public int sumRecursive() {
int sum = 0;
if (top != null) {
sum = top.sumRecursive();
}
return sum;
}
// public driver method for sumIterative
public int sumIterative() {
int sum = 0;
if (top != null) {
sum = top.sumIterative();
}
return sum;
}
}
public int sumRecursive() {
return sumRecursive(top);
}
public int sumRecursive(Node node){
if (node == null) {
return 0;
}
return node.item + sumRecursive(node.next);
}
// or to match your driver function
public int sumRecursive() {
if (top == null) {
return 0;
} else {
return top.sumRecursive();
}
}
// in Node class
public int sumRecursive(){
int sum = this.item;
if (this.next != null) {
sum += this.next.sumRecursive();
}
return sum;
}
public int sumRecursive(Node node){
if(node == null){
return 0;
}else{
return node.item + sumRecursive(node.next);
}
}
I'm trying to work on a method that will insert the node passed to it before the current node in a linked list. It has 3 conditions. For this implementation there cannot be any head nodes (only a reference to the first node in the list) and I cannot add any more variables.
If the list is empty, then set the passed node as the first node in the list.
If the current node is at the front of the list. If so, set the passed node's next to the current node and set the first node as the passed node to move it to the front.
If the list is not empty and the current is not at the front, then iterate through the list until a local node is equal to the current node of the list. Then I carry out the same instruction as in 2.
Here is my code.
public class LinkedList
{
private Node currentNode;
private Node firstNode;
private int nodeCount;
public static void main(String[] args)
{
LinkedList test;
String dataTest;
test = new LinkedList();
dataTest = "abcdefghijklmnopqrstuvwxyz";
for(int i=0; i< dataTest.length(); i++) { test.insert(new String(new char[] { dataTest.charAt(i) })); }
System.out.println("[1] "+ test);
for(int i=0; i< dataTest.length(); i++) { test.deleteCurrentNode(); }
System.out.println("[2] "+test);
for(int i=0; i< dataTest.length(); i++)
{
test.insertBeforeCurrentNode(new String(new char[] { dataTest.charAt(i) }));
if(i%2 == 0) { test.first(); } else { test.last(); }
}
System.out.println("[3] "+test);
}
public LinkedList()
{
setListPtr(null);
setCurrent(null);
nodeCount = 0;
}
public boolean atEnd()
{
checkCurrent();
return getCurrent().getNext() == null;
}
public boolean isEmpty()
{
return getListPtr() == null;
}
public void first()
{
setCurrent(getListPtr());
}
public void next()
{
checkCurrent();
if (atEnd()) {throw new InvalidPositionInListException("You are at the end of the list. There is no next node. next().");}
setCurrent(this.currentNode.getNext());
}
public void last()
{
if (isEmpty()) {throw new ListEmptyException("The list is currently empty! last()");}
while (!atEnd())
{
setCurrent(getCurrent().getNext());
}
}
public Object getData()
{
return getCurrent().getData();
}
public void insertBeforeCurrentNode(Object bcNode) //beforeCurrentNode
{
Node current;
Node hold;
boolean done;
hold = allocateNode();
hold.setData(bcNode);
current = getListPtr();
done = false;
if (isEmpty())
{
setListPtr(hold);
setCurrent(hold);
}
else if (getCurrent() == getListPtr())
{
System.out.println("hi" + hold);
hold.setNext(getCurrent());
setListPtr(hold);
}
else //if (!isEmpty() && getCurrent() != getListPtr())
{
while (!done && current.getNext() != null)
{
System.out.println("in else if " + hold);
if (current.getNext() == getCurrent())
{
//previous.setNext(hold);
//System.out.println("hi"+ "yo" + " " + getListPtr());
hold.setNext(current.getNext());
current.setNext(hold);
done = true;
}
//previous = current;
current = current.getNext();
}
}
System.out.println(getCurrent());
}
public void insertAfterCurrentNode(Object acNode) //afterCurrentNode
{
Node hold;
hold = allocateNode();
hold.setData(acNode);
if (isEmpty())
{
setListPtr(hold);
setCurrent(hold);
//System.out.println(hold + " hi");
}
else
{
//System.out.println(hold + " hia");
hold.setNext(getCurrent().getNext());
getCurrent().setNext(hold);
}
}
public void insert(Object iNode)
{
insertAfterCurrentNode(iNode);
}
public Object deleteCurrentNode()
{
Object nData;
Node previous;
Node current;
previous = getListPtr();
current = getListPtr();
nData = getCurrent().getData();
if (isEmpty()) {throw new ListEmptyException("The list is currently empty! last()");}
else if (previous == getCurrent())
{
getListPtr().setNext(getCurrent().getNext());
setCurrent(getCurrent().getNext());
nodeCount = nodeCount - 1;
}
else
{
while (previous.getNext() != getCurrent())
{
previous = current;
current = current.getNext();
}
previous.setNext(getCurrent().getNext());
setCurrent(getCurrent().getNext());
nodeCount = nodeCount - 1;
}
return nData;
}
public Object deleteFirstNode(boolean toDelete)
{
if (toDelete)
{
setListPtr(null);
}
return getListPtr();
}
public Object deleteFirstNode()
{
Object deleteFirst;
deleteFirst = deleteFirstNode(true);
return deleteFirst;
}
public int size()
{
return this.nodeCount;
}
public String toString()
{
String nodeString;
Node sNode;
sNode = getCurrent();
//System.out.println(nodeCount);
nodeString = ("List contains " + nodeCount + " nodes");
while (sNode != null)
{
nodeString = nodeString + " " +sNode.getData();
sNode = sNode.getNext();
}
return nodeString;
}
private Node allocateNode()
{
Node newNode;
newNode = new Node();
nodeCount = nodeCount + 1;
return newNode;
}
private void deAllocateNode(Node dNode)
{
dNode.setData(null);
}
private Node getListPtr()
{
return this.firstNode;
}
private void setListPtr(Node pNode)
{
this.firstNode = pNode;
}
private Node getCurrent()
{
return this.currentNode;
}
private void setCurrent(Node cNode)
{
this.currentNode = cNode;
}
private void checkCurrent()
{
if (getCurrent() == null) {throw new InvalidPositionInListException("Current node is null and is set to an invalid position within the list! checkCurrent()");}
}
/**NODE CLASS ----------------------------------------------*/
private class Node
{
private Node next; //serves as a reference to the next node
private Object data;
public Node()
{
this.next = null;
this.data = null;
}
public Object getData()
{
return this.data;
}
public void setData(Object obj)
{
this.data = obj;
}
public Node getNext()
{
return this.next;
}
public void setNext(Node nextNode)
{
this.next = nextNode;
}
public String toString()
{
String nodeString;
Node sNode;
sNode = getCurrent();
//System.out.println(nodeCount);
nodeString = ("List contains " + nodeCount + " nodes");
while (sNode != null)
{
nodeString = nodeString + " " +sNode.getData();
sNode = sNode.getNext();
}
return nodeString;
}
}
}
I have it working for my [1] and [2] conditions. But my [3] (that tests insertBeforeCurrentNode()) isn't working correctly. I've set up print statements, and I've determined that my current is reset somewhere, but I can't figure out where and could use some guidance or a solution.
The output for [1] and [2] is correct. The output for [3] should read
[3] List contains 26 nodes: z x v t r p n l j h f d b c e g i k m o q s u w y a
Thanks for any help in advance.
In your toString method you start printing nodes from the currentNode till the end of your list. Because you call test.last() just before printing your results, the currentNode will point on the last node of the list, and your toString() will only print 'a'.
In your toString() method, you may want to change
sNode = getCurrent();
with
sNode = getListPtr();
to print your 26 nodes.
For [3] you need to keep pointers to two nodes: one pointer in the "current" node, the one you're looking for, and the other in the "previous" node, the one just before the current. In that way, when you find the node you're looking in the "current" position, then you can connect the new node after the "previous" and before the "current". In pseudocode, and after making sure that the cases [1] and [2] have been covered before:
Node previous = null;
Node current = first;
while (current != null && current.getValue() != searchedValue) {
previous = current;
current = current.getNext();
}
previous.setNext(newNode);
newNode.setNext(current);