linked list get retrieveAt method - java

I have the following homework assignment:
Add a new method retrieveAt for the class IntSLList that takes an integer index position as a parameter.
The method returns the info inside the node at the index position. The index of the first node is 0. If the list is empty or the index is invalid, then display an error message.
I have implemented a solution using the following code:
public int retrieveAt(int pos){
IntSLLNode tmp;
int count = 0;
int c;
for(tmp = head; tmp != null; tmp = tmp.next){
count++;
}
if(isEmpty()|| count<pos){
return 0;
} else {
IntSLLNode tmp1 = head;
for(int i = 1; i < pos; i++){
if(tmp1.next == null)
return 0;
tmp1 = tmp1.next;
}
return tmp1.info;
}
}
It appears to traverse the list properly, but it does not retrieve the correct element.
An example case where this does not appear to give the correct output:
IntSLList myn = new IntSLList();
myn.addToHead(10);
myn.addToHead(20);
myn.addToHead(30);
myn.addToHead(40);
myn.addToTail(60);
myn.printAll();
int x = myn.retrieveAt(4);
if(x == 0)
System.out.println("NOT VALID ");
else
System.out.println("elm : " + x);
The output is:
40
30
20
10
60
elm : 10

int x=myn.retrieveAt(4);
you get the forth element, because you used the magical number 4. I'd suggest using either the number of elements in myn, or find out if you have an easier way to do this in your implementation of the IntSLList class.

I'm not sure what addToHead is supposed to do (add at the beginning or at the end).
I created this little example class that does both, please pick the method that fits your terminology.
The example is by no means complete, does no error checking, etc.
I tried to read your code and felt the for loops are very confusing.
Maybe this is what confuses you, too? That's why I made this example, that puts you into the position of each Node to figure out what to do next and works recursively.
The basic operations involved in adding an element are:
Do I know a next node? (is this the end of the chain?)
Should I pass my own value onto the next node or the value that was passed onto me? (where should a new value be added? end or beginning?)
public class Node
{
private Node next;
private Integer value;
public Node()
{
}
public void push(Integer value)
{
if(next != null)
next.push(value);
else
{
next = new Node();
this.value = value;
}
}
public void unshift (Integer value)
{
if(next != null)
{
next.unshift(this.value);
}
else
{
next = new Node();
next.value = this.value;
}
this.value = value;
}
public Integer get(int index)
{
if(index > 0)
return next.get(--index);
else
return value;
}
public int length()
{
if(next == null)
return 0;
else
return next.length() + 1;
}
public static void main(String[] args)
{
Node pushedList = new Node();
pushedList.push(10);
pushedList.push(20);
pushedList.push(30);
pushedList.push(40);
for(int i = 0; i < pushedList.length(); ++i)
{
System.out.println("pushed element #" + i +": " + pushedList.get(i));
}
Node unshiftedList = new Node();
unshiftedList.unshift(10);
unshiftedList.unshift(20);
unshiftedList.unshift(30);
unshiftedList.unshift(40);
for(int i = 0; i < unshiftedList.length(); ++i)
{
System.out.println("unshifted element #" + i +": " + unshiftedList.get(i));
}
Node mixedList = new Node();
mixedList.unshift(10);
mixedList.push(20);
mixedList.unshift(30);
mixedList.push(40);
for(int i = 0; i < mixedList.length(); ++i)
{
System.out.println("mixed element #" + i +": " + mixedList.get(i));
}
}
}
Edit: here's the output I receive:
pushed element #0: 10
pushed element #1: 20
pushed element #2: 30
pushed element #3: 40
unshifted element #0: 40
unshifted element #1: 30
unshifted element #2: 20
unshifted element #3: 10
mixed element #0: 30
mixed element #1: 10
mixed element #2: 20
mixed element #3: 40

Related

Count occurences of a given number in a LinkedList

Given a class LinkedList
public class LinkedList {
public Node head = null;
public class Node {
public int value;
public Node next;
}
}
I would like to add a method public int count(int value) that counts the amount of times a number occurs in a list.
I tried the following but it doesn't always work and I'm not sure what I am doing wrong.
public int count(int value) {
int counter = 0;
while(head != null) {
Node tmp = head.next;
while(tmp != null) {
if(head.value == value) {
counter++;
}
tmp = tmp.next;
}
head = head.next;
}
return counter;
}
This method works for 1 4 3 4 4 5, int value = 4 (which returns 3, as it should)
but for 1 2 3 4 4 5, int value = 4, it returns 1.
The simplest approach is: Iterate through the list and increase count for each node that contains 'value'. Since there were several problems in your code, I tried to explain the reason for each line with comments.
public int count(int value) {
int count = 0;
// 'tmp' is the node we are currently processing.
// Starting at the head...
Node tmp = head;
// while we not reached the end of the list
while(tmp != null) {
// if the node has the same value we are searching for
if(tmp.value == value) {
// increase count since we found the value
count++;
}
// Go to the next node (null if we reached the end of the list).
tmp = tmp.next;
}
return count;
}
Try this:
public int count(int value) {
int counter = 0;
Node tmp = head;
while (tmp != null) {
if(tmp.value == value) { // this line contained your biggest mistake
counter++;
}
tmp = tmp.next;
}
return counter;
}
You were not using value parameter at all in your method.
I would suggest you improve your Java learning through the use of an IDE that might give you hints of problems in your code. In this case, the lack of usage of value parameter in your method implementation.
I would suggest: IntelliJ IDEA, Eclipse or Visual Studio code. I am sure there are many more but these are the ones that I know.
This is a small example of what I mean:
Here is the recursive-approach of your problem:
int count(int value){
/* dummy node of your head */
LinkedList temp = this.head;
return count(temp, value);
}
private int count(LinkedList temp, int value){
int counter = 0;
if(temp == null){
return 0;
}
/* increment counter, when value is matched */
if(temp.value == value){
counter += 1;
}
counter += count(temp.next, value);
/* return the final result at the end */
return counter;
}

Java: Getting the char index element of a String that's stored in a Linked List

I'm new to programming and am working on a project I was hoping I could get some help with. The project specifications are as follows:
Implement the ADT character string as the class LinkedString by using
a linked list of characters. Include the following LinkedString
constructors and methods:
LinkedString(char[] value)
Allocates a new character linked list so that it represents the
sequence of characters currently contained in the character array
argument.
LinkedString(String original)
Initializes a new character linked list so that it represents the same
sequence of characters as the argument.
char charAt(int index)
Returns the character value at the specified index. The first
character in the linked character string is in position zero.
LinkedString concat(LinkedString str)
Concatenates the specified linked character string to the end of this
linked character string.
boolean isEmpty()
Returns true if, and only if length() is 0.
int length()
Returns the length of this linked character string.
LinkedString substring(int beginIndex, int endIndex)
Returns a new linked character string that is a substring of this
linked character string.
Implement LinkedString so that it mimics the Java String class. For
example, character positions should start at zero. Also, keep track
of the number of characters in the string with a variable named size;
the length should be determined without traversing the linked list and
counting the nodes. Remember to include a Test class which creates
one or more LinkedString objects and invokes each and every method in
your LinkedString ADT.
So I have three classes: the LinkedString class, the Node class, and a LinkedStringTest class that runs the main method. So far this is what I have for the LinkedString class:
public class LinkedString {
private int size; //var keeps track of number of characters
private Node head;
public LinkedString(){ //no argument constructor
head = null;
size = 0;
}
public LinkedString(char[] value){
if(value.length == 0)
return;
Node node = new Node(value[0]);
head = node;
size++;
Node current = head;
for(int nodeIndex = 1; nodeIndex < value.length; nodeIndex++){
node = new Node (value[nodeIndex]);
current.next = node;
size++;
}
}
public LinkedString(String original){
if(original.length() == 0)
return;
Node node = new Node(original.charAt(0));
head = node;
size++;
Node current = head;
for(int nodeIndex = 1; nodeIndex < original.length(); nodeIndex++){
node = new Node(original.charAt(nodeIndex));
current.next = node;
current = current.next;
size++;
}
}
public char charAt(int index){
Node current = head;
for(int nodeIndex = 0; nodeIndex < size; nodeIndex++){
if(nodeIndex == index){
return current.item;}
else{
current = current.next;
}
}
}
public LinkedString concat(LinkedString str){
if(str.head == null){
return this;
}
else if(head == null){
size = str.length();
return str;
}
else{
Node current = head;
while(current.next != null)
current = current.next;
current.next = str.head;
size += str.length();
return this;
}
}
public boolean isEmpty(){
return length() == 0;
}
public int length(){
return size;
}
public LinkedString substring(int beginIndex, int endIndex){
String substr = " ";
for(int nodeIndex = beginIndex; nodeIndex <= endIndex; nodeIndex++)
substr += charAt(nodeIndex);
LinkedString linkedSubstring = new LinkedString(substr);
return linkedSubstring;
}
}
This is my node class:
public class Node {
char item;
Node next;
public Node() {
setItem(' ');
setNext(null);
}
public Node(char newItem) {
setItem(newItem);
setNext(null);
}
public Node(char newItem, Node newNext) {
setItem(newItem);
setNext(newNext);
}
public Node(Node newNext) {
setItem(' ');
setNext(newNext);
}
public void setItem(char newItem) {
item = newItem;
}
public void setNext(Node newNext) {
next = newNext;
}
public char getItem() {
return item;
}
public Node getNext() {
return next;
}
}
And this is my LinkedStringTest class:
import java.util.Scanner;
public class LinkedStringTest {
public static void main (String args[]){
Scanner sc = new Scanner(System.in);
char[] chars = {'H', 'e', 'l', 'l', 'o'};
LinkedString list1 = new LinkedString(chars);
System.out.print("The original string is ");
System.out.println(chars);
System.out.println("Is the list empty? " + list1.isEmpty());
System.out.println("The characters length: " + list1.length());
System.out.println("Enter the position of a character and press Enter: ");
int pos1 = sc.nextInt();
System.out.println("The character at position " + pos1 + " is " + list1.charAt(pos1));
System.out.println("Enter a string: ");
String strng1 = sc.next();
LinkedString list2 = new LinkedString(strng1);
System.out.println("The string is " + list2);
System.out.println("That string concatanated with the original string is " + list1.concat(list2));
System.out.println("Enter the starting and ending index of part of a string ");
int start = sc.nextInt();
int end = sc.nextInt();
System.out.println("The substring from " + start + " to " + end + " is " + list1.substring(start,end));
}
}
This is the output I get when I run the test class:
run:
The original string is project2.LinkedString#55f96302
Hello
Is the list empty? false
The characters length: 5
Enter the position of a character and press Enter:
2
Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - missing return statement
at project2.LinkedString.charAt(LinkedString.java:64)
at project2.LinkedStringTest.main(LinkedStringTest.java:28)
C:\Users\Im\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 47 seconds)
As you can see, when I enter an index position (in this case the number 2) I get error messages. The first error (line 64) is at the start of my charAt method. The second error (line 28) is in the main method where I try to send the integer (in this case number 2) to the charAt method.
What am doing wrong with my charAt() method that makes it so that it cannot return the char at the requested index position?
Also, why when I tried to print out the object list1 near the beginning of the main method did I only get the reference address instead of the value itself?
System.out.print("The original string is " + list1);
System.out.println(chars);
I know I have lots of problems with this program, and I thank you in advance for any help you may be able to give me.
Solution:
Problem - Missing return statement.
In charAt method, return statement is inside an if condition of a for loop. This means that in the for loop, there will be times when program control will in "else". so, java is getting confused thinking that there is no return statement. one possible solution is as below which will fix the issue.
public char charAt(int index){
Node current = head;
for(int nodeIndex = 0; nodeIndex < size; nodeIndex++){
if(nodeIndex == index) {
break;
}
else{
current = current.next;
}
}
return current.item;
}
After the above change, if you run the code, you will get NullPointerException. reason is there is a subtle bug LinkedString constructor. Fix is as below - Add line current.next = node.
public LinkedString(char[] value){
if(value.length == 0)
return;
Node node = new Node(value[0]);
head = node;
size++;
Node current = head;
for(int nodeIndex = 1; nodeIndex < value.length; nodeIndex++){
node = new Node (value[nodeIndex]);
current.next = node;
current = node;
size++;
}
}
printing "list1" prints the reference and not the actual value. Solution is to override toString() method and provide a custom implementation as below:
Note that if you print any standard object in java, it calls its default toString() method which only prints a reference (mostly). by overriding toString method, we can pass the string that we want java to print.
#Override
public String toString() {
char value[];
value = new char[size];
Node n = head;
for(int i=0;i<size;i++){
value[i] = n.item;
n = n.next;
}
String str = String.copyValueOf(value);
return str;
}

How to construct a binary tree from just the level order traversal string

Consider a binary tree with the following properties:
An internal node (non-leaf node) has a value 1 if it has two children.
A leaf node has a value 0 since it has no children.
A level order traversal on the tree would generate a string of 1s and 0s (by printing the weird value at each node as they are visited). Now given this string construct the binary tree and perform a post order traversal on the tree. The post order string should be the output of the program.
For example: Input String is 111001000. Create a binary tree from this. Then perform the post order traversal on the tree which would result in an output: 001001011
The "crux" of the problem is to create the binary tree from just the level order string. How would I do this?
Taking your example of level order traversal - 111001000
The tree would be as follows
A
/ \
B C
/\ /\
D E F G
/\
H I
The logic is as follows.
1) Take first bit if its 1 (root) - then next 2^1 are values of children of that parent. So 2nd and 3rd bits are childern of A (root).
2) Go to next bit (1 for B) as its value is also 1 it also has 2 children and then next bit (1 for C) which also has 2 children. Second level is over and as we have 2 1's so 2^2 next bits are for level 3.
3) 111 001000 so this we have traversed and next 4 bits are children on 3rd level. 4th and 5th bits being 0 (D and E are leaf nodes and have no children - These will be children of B) and then F has bit value of 1 so 1110010 00 (bold figures) will be children of F. 7th bit is 0 and so G will also be leaf node.
4) Again loop through or try recusion - From 4th,5th and 6th and 7th bits only one bit is 1 so next 2^1 bits will be in next level and those will be children of F.
Once the tree is made then converting to PostFix is easy.
One possible solution (in less than an hour):
import java.util.ArrayList;
import java.util.List;
public class Main {
private static class Node {
private Node left;
private Node right;
}
private static Node buildTree(String input) {
char chars[] = input.toCharArray();
if (chars.length == 0) {
return null;
} else {
Node root = new Node();
List<Node> nodeList = new ArrayList<Node>();
nodeList.add(root);
int pos = 0;
while (!nodeList.isEmpty()) {
List<Node> nextList = new ArrayList<Node>();
for (Node n: nodeList) {
if (pos >= chars.length) {
throw new RuntimeException("Invalid input string");
}
char c = chars[pos++];
if (c == '1') {
n.left = new Node();
n.right = new Node();
nextList.add(n.left);
nextList.add(n.right);
} else if (c != '0') {
throw new RuntimeException("Invalid input string");
}
}
nodeList = nextList;
}
return root;
}
}
private static String postTraverse(Node n) {
if (n == null) {
return "";
} else if (n.left == null && n.right == null) {
return "0";
} else {
return postTraverse(n.left) + postTraverse(n.right) + "1";
}
}
public static void main(String[] args) {
Node tree = buildTree(args[0]);
System.out.println(postTraverse(tree));
}
}
If it was allowed, I would use a binary heap as a helper here. In a binary heap implemented using a standard table, given an index of an element we can easily calculate its parent's index: int parent = (index-1)/2;. Knowing this, we would need to start at the beginning of our table and do the folowing:
Set the binaryHeap[0] to the first number from the input stream;
for all the remaining elements in input stream:
do{
binaryHeap[heapIndex] = -1;
if (parent(heapIndex) = 1)
binaryHeap[heapIndex] = nextElementFromTheInputStream;
heapIndex++;
}
while(binaryHeap[heapIndex - 1] == 0);
So basically, we move through our table. We initialize each field (except root at 0) to be -1, which means there is no node there. Then we check if the parent of that field was 1. If it was, then we place next element from the input stream on our current index in the heap (heapIndex). If the parent of a current field is 0, we just go further, because that means our parent is a leaf and is not supposed to have any children.
Then we can run post-order algorithm on the heap (probably it would be worth implementing some security-code, so that no element with "-1" is placed in the output stream. Just interpret leftChild(heapIndex) == -1; or rightChild(heapIndex) == -1; to be NULL).
This algorithm is probably quite inefficient in terms of memory, but I hope it is quite easy to understand.
First, I assume that your level order traversal is basically a BFS.
Now, let's have a look at the string. Performing the BFS, we print "1" if the current node's got two sons. Otherwise, it's a leaf and we print 0, terminating the processing of the current branch.
Consequently, during the reverse task, we can remember the list of open branches' last nodes and append the incoming nodes there.
Let's demonstrate this approach on an example:
Level 1:
Tree :
1 - id 0
Open branches : 0 0 (left and right son)
Remaining string : 11001000
*********
Level 2:
Tree :
1
1 1
Open branches : 1 1 2 2
Remaining string : 001000
*********
Level 3:
Tree :
1
1 1
0 0 1 0
Open branches : 5 5
Remaining string : 00
Level 4:
Tree :
1
1 1
0 0 1 0
0 0
No more input, we're done.
Having the tree, the post-order traversal is trivial.
And the code (it assumes that the tree is quite dense, otherwise it's not very memory efficient):
import java.util.ArrayDeque;
import java.util.Queue;
public class Main {
static final int MAX_CONST = 50;
public static void main(String[] args) {
String evilString = "111001000"; // Assuming this string is a correct input
char[] treeRepr = new char[MAX_CONST];
Queue<Integer> q = new ArrayDeque<Integer>();
q.add(0);
for (int i = 0; i < evilString.length(); ++i) {
int index = q.remove();
char ch = evilString.charAt(i);
if (ch == '1') {
q.add(2*(index+1)-1);
q.add(2*(index+1));
}
treeRepr[index] = ch;
// System.out.println(q.size());
}
System.out.println(arrToString(treeRepr, 0, new StringBuilder()));
}
public static StringBuilder arrToString(char[] array, int index, StringBuilder sb) {
if (array[index] == '1')
{
arrToString(array, 2*(index+1)-1, sb);
arrToString(array, 2*(index+1), sb);
}
sb.append(array[index]);
return sb;
}
}
Here is a pretty simple solution. Not really optimal with
respect to memory though, as I build a complete/full tree first
and then I mark which nodes actually exist in our tree. So this
could be optimized a bit, I guess.
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;
class Node {
public Node left;
public Node right;
public Integer id;
public boolean exists;
}
public class Test32 {
public static void main(String[] args) {
HashMap<Integer, Node> mp = new HashMap<Integer, Node>();
String str = "110101000";
int sz = (int)Math.pow(2, str.length() + 1);
for (int i=0; i<sz; i++){
Node nd = new Node();
nd.id = i;
mp.put(nd.id, nd);
}
for (int i=0; i<sz; i++){
Node nd = mp.get(i);
if (2*i < sz) nd.left = mp.get(2*i + 1);
if (2*i + 1 < sz) nd.right = mp.get(2*i + 2);
}
Queue<Integer> visit = new LinkedList<Integer>();
visit.add(0); // id = 0;
int j = 0;
int id = -1;
while (!visit.isEmpty()){
id = visit.poll();
if (str.charAt(j) == '1'){
mp.get(id).exists = true;
visit.add(2*id + 1);
visit.add(2*id + 2);
}else{
mp.get(id).exists = true;
}
j++;
}
System.out.println("NODES:");
for (int i=0; i<sz; i++){
if (mp.get(i).exists){
System.out.println(i);
}
}
System.out.println();
System.out.println("EDGES:");
for (int i=0; i<sz; i++){
if (mp.get(i).exists){
if (mp.get(2 * i + 1).exists){
System.out.println(i + " --> " + (2*i+1));
}
if (mp.get(2 * i + 2).exists){
System.out.println(i + " --> " + (2*i+2));
}
}
}
}
}
And here is the same solution simplified edition.
No trees or maps, just a boolean array. If some node
k has children these children are 2*k+1 and 2*k+2.
In the last loop while printing the edges one can also
construct an actual binary tree.
import java.util.LinkedList;
import java.util.Queue;
public class Test32 {
public static void main(String[] args) {
String str = "110101000";
int sz = (int)Math.pow(2, str.length() + 1);
boolean exists[] = new boolean[sz];
Queue<Integer> visit = new LinkedList<Integer>();
visit.add(0); // id = 0;
if (str.charAt(0) == '1'){
exists[0] = true;
}
int j = 0;
int id = -1;
while (!visit.isEmpty()){
id = visit.poll();
if (str.charAt(j) == '1'){
exists[id] = true;
visit.add(2*id + 1);
visit.add(2*id + 2);
}else{
exists[id] = true;
}
j++;
}
// System.out.println("");
System.out.println("NODES:");
for (int i=0; i<sz; i++){
if (exists[i]){
System.out.println(i);
}
}
System.out.println("");
System.out.println("EDGES:");
for (int i=0; i<sz; i++){
if (exists[i]){
if (exists[2*i+1]){
System.out.println(i + " --> " + (2*i+1));
}
if (exists[2*i+2]){
System.out.println(i + " --> " + (2*i+2));
}
}
}
}
}
Conceptually more simpler I think.
import java.util.LinkedList;
import java.util.Queue;
class WeirdBinaryTree
{
static class Node
{
private Node right;
private Node left;
private int weirdValue;
public void setWeirdValue(int value)
{
weirdValue=value;
}
}
private static Node makeTree(String str)throws Exception
{
char[] array=str.toCharArray();
Node root=new Node();
Queue<Node> list=new LinkedList();
list.add(root);
int i=0;
Queue<Node> nextList=new LinkedList<Node>();
while(!list.isEmpty())
{
if(array[i++]=='1')
{
Node temp=list.poll();
temp.left=new Node();
temp.right=new Node();
temp.setWeirdValue(1);
nextList.add(temp.left);
nextList.add(temp.right);
}
else
{
list.poll();
}
if(list.isEmpty())
{
list=nextList;
nextList=new LinkedList<Node>();
}
}
return root;
}
private static void postTraversal(Node localRoot)
{
if(localRoot!=null)
{
postTraversal(localRoot.left);
postTraversal(localRoot.right);
System.out.print(localRoot.weirdValue);
}
}
public static void main(String[] args)throws Exception
{
postTraversal(makeTree("111001000"));
}
}

Issue with btree algorithm

I've been searching all over for some pointers and have been coming up a bit short. I have an assignment for a project where we have to make a btree implementation by extending a 234 Tree class that was given to us.
The 234Tree class is working while the tree is still a 234 tree. It seems that using the insert method from this class breaks when I try to use this as a btree. I've copied the insert method into my btree class as an override in case I have to change something, that way the 234 tree split will still work.
Here's a link to my btree class at pastebin http://pastebin.com/TcP0UMA2
I use all of this from a command prompt. Here's the output when I run it
Enter first letter of show, insert, find, change, read, or quit: s<br/>
level=0 child=0 /20/30/50/70/<br/>
level=1 child=0 /10/<br/>
level=1 child=1 /25/<br/>
level=1 child=2 /35/40/45/<br/>
level=1 child=3 /60/<br/>
level=1 child=4 /80/90/100/<br/>
Enter first letter of show, insert, find, change, read, or quit: i<br/>
Enter value to insert: 85<br/>
Moving 2 items. Those values are 50, 70.<br/>
Exception in thread "main" java.lang.NullPointerException<br/>
at frankaddeliaproject2.BTree.insert(BTree.java:115)<br/>
at frankaddeliaproject2.Tree234App.main(Tree234App.java:43)<br/>
Java Result: 1
The problem I notice ends up being when the parent node becomes full (in this instance it's order of 5, so it wants to split the node on the 5th insert). That's why when trying to insert 85 it breaks at this point.
while(true)
{
if( curNode.isFull() ) // if node full,
{
split(curNode); // split it
curNode = curNode.getParent(); // back up
// search once
curNode = getNextChild(curNode, dValue);
} // end if(node is full)
The nullPointerException is at the line that has this statement:
if( curNode.isFull())
When I look at this block of code I can figure out that it's checking if curNode is full, so it'll run through the first time and the issue seems to be coming when
curNode = getNextChild //...
Because there technically isn't a child after this one. I'm mainly unsure of how to fix it from this point.
Thanks in advance, any help is appreciated!
-Frank
EDIT:
It looks like my link to the class gets a little buried. I'll post it below if that's easier
public class BTree extends Tree234 {
public void split(Node thisNode) // split the node
{
// assumes node is full
int tmp = Node.getOrder();
int counter = 0;
//figures out number of children to move during a move (2^n < x < 2^n+1)
while(tmp >= 2)
{
tmp /= 2;
counter++;
}
DataItem[] items = new DataItem[counter + 1];
for(int x = counter; x > 0; x--)
{
items[x] = thisNode.removeItem();
}
DataItem itemB;
Node parent;
Node[] children = new Node[counter];
int itemIndex;
itemB = thisNode.removeItem(); // this node
//makes array of children to move
int tmpcount = 0;
for(int i = counter; i > 0; i--)
{
children[tmpcount] = thisNode.disconnectChild(Node.getOrder() - i);
tmpcount++;
}
Node newRight = new Node(); // make new node
if(thisNode==root) // if this is the root,
{
root = new Node(); // make new root
parent = root; // root is our parent
root.connectChild(0, thisNode); // connect to parent
}
else // this node not the root
parent = thisNode.getParent(); // get parent
// deal with parent
itemIndex = parent.insertItem(itemB); // item B to parent
int n = parent.getNumItems(); // total items?
for(int j=n-1; j>itemIndex; j--) // move parent's
{ // connections
Node temp = parent.disconnectChild(j); // one child
parent.connectChild(j+1, temp); // to the right
}
// connect newRight to parent
parent.connectChild(itemIndex+1, newRight);
// deal with newRight
// moves items to newRight
// then alerts how many items are being moved and the values
String msg = "Moving " + counter + " items. Those values are ";
for(int y = 0; y < counter + 1; y++)
{
if(items[y] == null)
{
continue;
}
newRight.insertItem(items[y]);
//build output message
if(y < counter)
msg += items[y].dData + ", ";
else
msg += items[y].dData + ". ";
}
//outputs message
System.out.println(msg);
//reconnect children to new parent
for(int j = 0; j < counter; j++)
{
newRight.connectChild(j, children[j]);
}
} // end split()
// -------------------------------------------------------------
// gets appropriate child of node during search for value
public void insert(long dValue)
{
Node curNode = root;
DataItem tempItem = new DataItem(dValue);
while(true)
{
if( curNode.isFull() ) // if node full,
{
split(curNode); // split it
curNode = curNode.getParent(); // back up
// search once
curNode = getNextChild(curNode, dValue);
} // end if(node is full)
else if( curNode.isLeaf() ) // if node is leaf,
break; // go insert
// node is not full, not a leaf; so go to lower level
else
curNode = getNextChild(curNode, dValue);
} // end while
curNode.insertItem(tempItem); // insert new DataItem
} // end insert()
// -------------------------------------------------------------
}
I don't know whether you have an underlying problem from just that snippet but you can solve the NullPointerException by simply checking curNode first.
if(curNode != null && curNode.isFull() ) // if node full,
{
split(curNode); // split it
curNode = curNode.getParent(); // back up
// search once
curNode = getNextChild(curNode, dValue);
} // end if(node is full)

Java: NPE in Circular Linked List :(

import javax.swing.JOptionPane;
public class RotateArrayCircularLL
{
private Node head=null;
public void init()
{
int choice = 0;
while (choice != -1){
choice = Integer.parseInt(JOptionPane.showInputDialog("Enter -1 to stop loop, 1 to continue"));
if(choice == -1)
break;
inputNum();
}
printList();
}
public void inputNum()
{
Node n;
Node temp;
int k;
k = Integer.parseInt(JOptionPane.showInputDialog(null,"Enter a number:"));
n = new Node(k);
if (head == null) {
head = n;
} else {
temp = head;
while (temp.getNext() != null)
temp = temp.getNext();
temp.setNext(n);
}
}
public void printList()
{
Node temp = head;
int count = Integer.parseInt(JOptionPane.showInputDialog("Enter the value to shift to the right"));
for (int i = 1; i <= count; i++) // Rotates the head
temp = temp.getNext();
for (Node c = temp; c != null && c.getNext() != head; c= c.getNext()){ // Prints the new LL
System.out.print(c.getInfo());
}
}
}
I get an NPE during the second for loop. I understand that it is giving me a NPE because I reach the end of the list, but how can I stop it from doing this?
It appears from the behavior you are seeing that one of the nodes in your linked list is returning null instead of the next element of the list. At a guess, I'd suggest that the last node of your list is probably not pointing to the first node of your list. Hence as Hovercraft Full Of Eels suggests, you don't really have a properly circular linked list. If you can post the code showing how temp is populated, it may be possible to give a more concrete solution to your issue. Otherwise, you need to treat the case where getNext() returns null as a special case and ensure that you instead get the first element from the initial list.

Categories