Implementing a Circular Single Linked List using a scanner - java

This is a given activity where we should create a method for inserting a node and it uses a scanner for its input. So far, I can input 3 objects from the list but here comes the problem when I try to add another one:
It goes something like this: 1,2,3 and when I try to add another it goes to this 1,2,4 but want I want is this 1,2,3,4.
I deeply appreciate your help in advance.
Here is the main method:
import java.util.Scanner;
public class MySinglyLinkedCircularListMain {
public static void main(String[] args) throws ListOverflowException {
Scanner keyboard = new Scanner(System.in);
MySinglyLinkedCircularList<Node> singlyLinkedCircularList = new MySinglyLinkedCircularList<>();
while (true) {
System.out.println("+---------------------------------------------------+");
System.out.println("| Select the Number to be executed: |\n" +
"| 1) Insert an element |\n" +
"| 2) Delete an element from the list |\n" +
"| 3) Get an element from the list |\n" +
"| 4) Search an element in the list |\n" +
"| 5) Number of elements in the list |\n" +
"| 6) Show the elements in the list |");
System.out.print("+---------------------------------------------------+ \n");
System.out.print("Input your choice: ");
int intInput = keyboard.nextInt();
if (intInput == 1) {
singlyLinkedCircularList.insert(new Node(singlyLinkedCircularList));
} else if (intInput == 2) {
singlyLinkedCircularList.delete(new Node(singlyLinkedCircularList));
} else if (intInput == 3) {
singlyLinkedCircularList.getElement(new Node(singlyLinkedCircularList));
} else if (intInput == 4) {
singlyLinkedCircularList.search(new Node(singlyLinkedCircularList));
} else if (intInput == 5){
System.out.println("The current capacity of the single circular linked list is "
+ singlyLinkedCircularList.getSize());
} else if (intInput == 6) {
singlyLinkedCircularList.showAllElements();
System.out.println();
}
}
}
}
Here is the node class
public class Node<T> {
T data;
Node<T> next;
public Node(T data) {
this.data = data;
next = null;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public void setNext(Node<T> node) {
next = node;
}
public Node<T> getNext() {
return next;
}
}
Here's the class for the insert method
import java.util.NoSuchElementException;
import java.util.Scanner;
public class MySinglyLinkedCircularList<E> implements MyList<E> {
Scanner keyboard = new Scanner(System.in);
int size;
Node<E> startNode;
Node<E> endNode;
public MySinglyLinkedCircularList() {
size = 0;
startNode = endNode = null;
}
public int getSize() {
return size;
}
public void insert(E data) throws ListOverflowException {
System.out.print("Input the element you want: ");
data = (E) keyboard.next();
Node<E> newNode = new Node(data);
if (startNode == null) {
startNode = endNode = newNode;
startNode.next = startNode;
size++;
System.out.println("Element " + startNode.getData() + " has been stored in position "
+ getSize() + " and is now referenced itself");
} else {
Node<E> addNode = endNode;
for (int i = 0; i < getSize(); i++) {
addNode = addNode.getNext();
}
addNode.next = newNode;
newNode.next = startNode;
size++;
}
}
Here's the show elements method
public void showAllElements() {
Node<E> showNode = startNode;
int i = 0;
System.out.print("Here are the current elements: ");
while (i<getSize()) {
System.out.print(showNode.getData() + " ");
showNode = showNode.getNext();
i++;
}
System.out.print(showNode.getData());
}
Here's the interface
public interface MyList<E> {
public int getSize();
public void insert(E data) throws ListOverflowException;
public E getElement(E data) throws NoSuchElementException;
public boolean delete(E data); // returns false if the data is not deleted in the list
public boolean search(E data);
public void showAllElements();
}

This is problematic:
public void insert(E data) throws ListOverflowException {
System.out.print("Input the element you want: ");
data = (E) keyboard.next(); // ***** here *****
Your method accepts an E data parameter, insert(E data) and yet promptly discards any result held by the parameter in the second line of the method, data = (E) keyboard.next();, replacing it with Scanner input that shouldn't even be there. The MySinglyLinkedCircularList class should not have a Scanner object, nor should it take user input, but rather should handle the circular list's logic, and that's it. It shouldn't even have println statements, except perhaps temporary println's that you may usind during creation for debugging purposes only. Keep all UI code (user interface code -- Scanner input and println statements) together in the UI class.
Note, that I don't know if this is the cause of your full error, and to check for that will require more intense debugging, debugging that I urge you to do more of yourself, since it is both your responsibility to debug first, and it is a necessary and useful skill that only gets better with use. If you're not sure how to go about doing this, then please check out How to debug small programs. It won't solve your direct problem, but it will give you steps that you can follow that should help you solve it yourself, or even if that is not successful, then at least help you to better isolate your problem so that your question can be more focused and easier to answer.

Related

Tree traversing doesn't print desired solution

(java)
I have class called Node, which has following fields:
value (integer)
connectedNodes (array of Node objects, always has same size = 2)
combination (object of Combination class)
Combination class has one field called messageContext, let's just say that it's a message which needs to be shown on the screen when something happens (described later).
Also, we have one Tree object, which has only one field: root (Node object)
Now, let's say that we have one String called combinationStr = "1121". Now, we use Tree's method called addCombination:
public void addCombination(Combination finalCombination, Node current, String combination, int counter) {
if(counter==combination.length()) {
return;
}
int value = combination.charAt(counter)-48;
if(current.connectedNodes[value-1]==null) {
current.connectedNodes[value-1] = new Node(value);
}
if(counter==combination.length()-1) {
current.combination = finalCombination;
return;
}
addCombination(finalCombination,current.connectedNodes[value-1],combination,counter+1);
}
finalCombination object is an object that is going to be assigned to the last Node's combination field, added to the Tree for one combinationStr. So, we use this function to create the Tree-like structure that has path: -1 (root) -> 1 -> 1 -> 2 -> 1
When we come to the last one, traversing the Tree, we should see message appear. This is the messageContext of finalCombination.
Okay so, now let's use while(true) loop that will let us input a number, which will be like a path-chooser. If we input 1, we will go to node 1 and have other options to choose.
While loop looks like this:
Scanner scanner = new Scanner(System.in);
Node currentNode = tree.root;
while(true) {
for(Node node: currentNode.connectedNodes) {
if(node!=null) {
System.out.print(node.value + " ");
continue;
}
System.out.print("nullnode ");
}
System.out.println("");
if(currentNode.combination!=null) {
System.out.println(currentNode.combination.messageContext);
}
if(currentNode.connectedNodes[0]==null && currentNode.connectedNodes[1]==null) {
currentNode = tree.root;
System.out.println("root");
}
int x = scanner.nextInt();
currentNode = tree.takeStep(currentNode,x);
}
So, what are we doing here is actually printing the value of current Node, then printing values of Node's we can go to. If Node doesn't exist, we print nullnode.
The takeStep() method looks like this:
public Node takeStep(Node current, int value) {
if(current.connectedNodes[value-1]!=null) {
return current.connectedNodes[value-1];
}
return this.root;
}
It just checks if there is a node we want to go to and returns that node, if it does. If it doesn't exist, it will return us to root.
But, what's the problem with this code ?
Well, look at the whole main class:
Tree tree = new Tree(new Node(-1));
String[] combination = {"1121","11","2212"};
for(String s: combination) {
Combination tempCombination = new Combination();
tempCombination.messageContext = s + " ova poruka";
tree.addCombination(tempCombination,tree.root,s,0);
tree.traverse(tree.root);
System.out.println("END");
}
Scanner scanner = new Scanner(System.in);
Node currentNode = tree.root;
while(true) {
System.out.println(currentNode.value);
for(Node node: currentNode.connectedNodes) {
if(node!=null) {
System.out.print(node.value + " ");
}
else {
System.out.print("nullnode ");
}
}
int x = scanner.nextInt();
if(currentNode.combination!=null) {
System.out.println(currentNode.combination.messageContext);
if(currentNode.connectedNodes[0]==null && currentNode.connectedNodes[1]==null) {
currentNode = tree.root;
break;
}
}
currentNode = tree.takeStep(currentNode,x);
}
When we enter number x, we will call takeStep and check if that node exists connected to current one. But the problem is: When we input 1, it prints everything normally, when we input 1 again, it prints everything normally, when we input 2, it prints everything normally... but when we input 1 again, it says there are 2 nullnodes, and for some reason it doesn't change to root. Can anyone help me please? Here are the full classes:
NODE:
public class Node {
int value;
Node[] connectedNodes = {null,null};
Combination combination;
public Node(int value) {
this.value = value;
this.combination = null;
}
}
TREE:
public class Tree {
Node root;
public Tree(Node root) {
this.root = root;
}
public void addCombination(Combination finalCombination, Node current, String combination, int counter) {
if(counter==combination.length()) {
return;
}
int value = combination.charAt(counter)-48;
if(current.connectedNodes[value-1]==null) {
current.connectedNodes[value-1] = new Node(value);
}
if(counter==combination.length()-1) {
current.combination = finalCombination;
return;
}
addCombination(finalCombination,current.connectedNodes[value-1],combination,counter+1);
}
public void traverse(Node current) {
System.out.print(current.value+ " ");
for(Node node: current.connectedNodes) {
if(node!=null) {
traverse(node);
}
}
}
public Node takeStep(Node current, int value) {
if(current.connectedNodes[value-1]!=null) {
return current.connectedNodes[value-1];
}
return this.root;
}}
COMBINATION:
public class Combination {
String messageContext;
}
Can you please help me ? I just want to reset to root when it hasn't anywhere to go else ? Thank you in advance!
I ran your code and found out that you are storing the message context in the parent node instead of the actual node which marks the end of the combination. So I changed this piece of code in addCombination.
public void addCombination(Combination finalCombination, Node current, String combination, int counter) {
if (counter == combination.length()) {
//Storing at the original node.
current.combination = finalCombination;
return;
}
int value = combination.charAt(counter) - 48;
if (current.connectedNodes[value - 1] == null) {
current.connectedNodes[value - 1] = new Node(value);
}
addCombination(finalCombination, current.connectedNodes[value - 1], combination, counter + 1);
}
And changed following in the main code.
while (true) {
System.out.println(currentNode.value);
//Moved it up now as the node it self has the message context.
if (currentNode.combination != null) {
System.out.println(currentNode.combination.messageContext);
if (currentNode.connectedNodes[0] == null && currentNode.connectedNodes[1] == null) {
currentNode = tree.root;
continue;
}
}
for (Node node : currentNode.connectedNodes) {
if (node != null) {
System.out.print(node.value + " ");
} else {
System.out.print("nullnode ");
}
}
int x = scanner.nextInt();
currentNode = tree.takeStep(currentNode, x);
}
Now try the code it is resetting to root as expected.

Tree iterator in Java

I have implemented a code which adds elements in a tree and prints them in increasing order. However my aim is to learn iterators and want to replace the inOrder() function with an iterator function. How can I do this?
import java.util.InputMismatchException;
import java.util.Scanner;
import javax.xml.soap.Node;
class Tree
{
public final int mVal;
public Tree mLeft;
public Tree mRight;
public Node next;
public Tree(int val)
{
mVal = val;
}
public void add(int val)
{
if (val < mVal)
{
if (mLeft == null)
mLeft = new Tree(val);
else
mLeft.add(val);
}
else
{
if (val > mVal)
{
if (mRight == null)
mRight = new Tree(val);
else
mRight.add(val);
}
}
}
public String inOrder()
{
return ((mLeft == null) ? "" : mLeft.inOrder())
+ mVal + " "
+ ((mRight == null) ? "" : mRight.inOrder());
}
public static void main(String[] args)
{
Tree t = new Tree(8);
Scanner scanner = new Scanner(System.in);
boolean continueLoop = true; // determines if more input is needed
for (int i = 1; i < 9; ++i)
{
try // read two numbers and calculate quotient
{
System.out.print("Please enter a random integer : ");
int stackInt = scanner.nextInt();
t.add(Integer.valueOf(stackInt));
} // end try
catch (InputMismatchException inputMismatchException){
System.err.printf("\nException: %s\n", inputMismatchException);
scanner.nextLine(); //discard input so user can try again
System.out.println("You must enter integers. Please try again.\n");
} // end catch
}
System.out.println("Values in order = "+ t.inOrder());
}
}
look at this picture
First Step: if node has a left child, visit left child and do the first step with the child
Second Step: node has no left child (or we visited the left child already), add it to the inorder list
Third Step: first step with right child
i didnt test it
#Override
public String toString() {
return String.valueOf(mVal);
}
public String inOrder(Tree root) {
List<Tree> inOrder = new ArrayList<>();
inOrderRecursively(root, inOrder);
return inOrder.toString();
}
private void inOrderRecursively(Tree Node, List<Tree> inOrder) {
if (Node.mLeft != null) {
inOrderIt(Node.mLeft, inOrder);
}
inOrder.add(Node);
if (Node.mRight != null) {
inOrderIt(Node.mRight, inOrder);
}
}
greetings

Generic Linked List of Objects (Java)

I'm pretty new to Java, with this being my second class (in College) using it. Towards the beginning of the semester, I made a simple class representing Zombies that holds their age, type, and name. Later on, I made a linked list of integers. Now, I need to make a generic linked list that can hold these 'Zombies'. I also have to make a menu that allows me to add, remove, count, and display 'Zombies'. I've been staring at this for hours, going through my book, and looking online for the answer to my problem. I can add and display these 'Zombies', but counting them in the list and trying to remove them simply has it tell me there's none with the parameters I entered. In other words, there might be a problem with how I compare the 'Zombies'. Here's my code. I understand it's a good 300 lines of code to look through... but i'm out of ideas.
Zombie.java
public class Zombie
{
private String zAge;
private String zType;
private String zName;
public Zombie(String zA, String zT, String zN)
{
zAge = zA;
zType = zT;
zName = zN;
}
public void setZAge(String zA)
{
zAge = zA;
}
public void setZType(String zT)
{
zType = zT;
}
public void setZName(String zN)
{
zName = zN;
}
public String getZAge()
{
return zAge;
}
public String getZType()
{
return zType;
}
public String getZName()
{
return zName;
}
public boolean equals(Zombie zomb)
{
if(zomb.getZAge() == zAge && zomb.getZType() == zType && zomb.getZName() == zName)
return true;
else
return false;
}
}
LinkedBag.java
public class LinkedBag<E>
{
//Head node and number of nodes in bag
private Node<E> head;
private int manyNodes;
//Constructor
public LinkedBag()
{
head = null;
manyNodes = 0;
}
//Returns the number of nodes in the bag
public int getSize()
{
return manyNodes;
}
//Returns the node that is at the head of the linked list
public Node<E> getListStart()
{
return head;
}
//Adds a node to the beginning of the list
public void add(E element)
{
head = new Node<E>(element,head); //Creates a new node pointing to the head and sets the head of the linked bag to the new Node
manyNodes++; //Increments Node counter
}
//Counts the number of times Node [target] occurs within the bag
public int countOccurences(E target)
{
int count = 0; //Initializes incrementable counter
if(head==null) //Checks if bag is empty and returns null if bag is empty
return 0;
if(head.getData().equals(target)) //Checks if the head of the linked list is [target]
count++; //Increments counter
Node<E> cursor = head; //Sets temporary Node [cursor] to the same value and pointer as head
while(cursor.getLink() != null) //Loops until the next Node contains no value
{
if(cursor.getLink().getData().equals(target)) //Checks if the value of the next Node is [target]
count++; //Increments counter
cursor=cursor.getLink(); //Cursor continues down linked list
}
return count; //Returns incremented int [count], number of occurences of [target]
}
//Checks if Node [target] exists within the bag
public boolean exists(E target)
{
if(head.getData().equals(target)) //Checks if the head of the linked list is [target]
return true;
Node<E> cursor = head; //Sets temporary Node [cursor] to the same value and pointer as head
while(cursor.getLink() != null) //Loops until the next Node contains no value
{
if(cursor.getData().equals(target)) //Checks if current Node is [target] and returns true if true
return true;
cursor=cursor.getLink(); //Cursor continues down linked list
}
return false; //Returns false if cursor goes through entire linked list and [target] isn't found
}
//Checks if Node [target] exists within the bag and removes the first occurence of it
public boolean remove(E target)
{
if(head==null) //Returns false if bag is empty
return false;
if(head.getData().equals(target)) //If the head Node's data is [target]
{
head = head.getLink(); //Make the next Node the head
manyNodes--; //Decrements Node counter
return true; //Returns true, found [target]
}
Node<E> cursor = head; //Sets temporary Node [cursor] to the same value and pointer as head
while(cursor.getLink() != null) //Loops until the next Node contains no value
{
cursor = cursor.getLink(); //Cursor continues down linked list
if(cursor.getLink().getData().equals(target)) //If the next node's data is [target]
{
cursor.setLink(cursor.getLink().getLink()); //Sets current Node's link to the next Node's link, by passing the next Node
manyNodes--; //Decrements Node counter
return true; //Returns true, found [target]
}
}
return false; //Returns false, [target] not found
}
}
Node.java
public class Node<E>
{
private E data;
private Node<E> link;
public Node(E initialData, Node<E> initialLink)
{
data = initialData;
link = initialLink;
}
public E getData()
{
return data;
}
public Node<E> getLink ()
{
return link;
}
public void setData(E element)
{
data = element;
}
public void setLink(Node<E> newLink)
{
link = newLink;
}
}
And this is the menu file that the user interacts with
ZombiesProj2.java
import java.util.Scanner;
public class ZombiesProj2
{
public static void main(String[] args) throws InterruptedException
{
LinkedBag<Zombie> zBag = new LinkedBag<Zombie>(); //Linked bag to hold Zombie Objects
String choice = "";
Scanner input = new Scanner(System.in);
while(!choice.equalsIgnoreCase("x"))
{
//Menu
System.out.println("\nSac de Zombi\n");
System.out.println("S - Display size of bag");
System.out.println("A - Add 'Zombie' to bag");
System.out.println("R - Remove 'Zombie' from bag");
System.out.println("F - Find 'Zombie' in bag");
System.out.println("D - Display contents of bag");
System.out.println("X - Exit");
System.out.print("Enter Selection: ");
//Input and Output
choice = input.nextLine();
if(choice.equalsIgnoreCase("s"))
{
System.out.println("\nSize = " + zBag.getSize() + "\n");
}
else if(choice.equalsIgnoreCase("a")) //adds zombie
{
String zAge;
String zType;
String zName;
System.out.print("How many years has this zombie ROAMED THE EARTH: ");
zAge = input.nextLine();
System.out.print("What type of zombie is it: ");
zType = input.nextLine();
System.out.print("What would you like to name this zombie: ");
zName = input.nextLine();
Zombie newZomb = new Zombie(zAge,zType,zName);
zBag.add(newZomb);
}
else if(choice.equalsIgnoreCase("r")) //removes zombie
{
String zAge;
String zType;
String zName;
System.out.print("How many years has this zombie ROAMED THE EARTH: ");
zAge = input.nextLine();
System.out.print("What type of zombie is it: ");
zType = input.nextLine();
System.out.print("What is the name of the zombie: ");
zName = input.nextLine();
Zombie rZomb = new Zombie(zAge,zType,zName);
zBag.remove(rZomb);
}
else if(choice.equalsIgnoreCase("f")) //counts number of matching zombies
{
String zAge;
String zType;
String zName;
System.out.print("How many years has this zombie ROAMED THE EARTH: ");
zAge = input.nextLine();
System.out.print("What type of zombie is it: ");
zType = input.nextLine();
System.out.print("What is the name of the zombie: ");
zName = input.nextLine();
Zombie fZomb = new Zombie(zAge,zType,zName);
System.out.println("The " + zAge + " year old zombie type " + zType + " named " + zName + " occurs " + zBag.countOccurences(fZomb)+ " time(s)");
}
else if(choice.equalsIgnoreCase("d")) //displays entire zombie 'bag'
{
Node cursor = zBag.getListStart();
Zombie dZomb;
while(cursor !=null)
{
dZomb = (Zombie)cursor.getData();
System.out.print("[Zombie "+dZomb.getZAge()+" "+dZomb.getZType()+" "+dZomb.getZName()+"],");
cursor = cursor.getLink();
}
}
else if(!choice.equalsIgnoreCase("x"))
{
System.out.println("Error: Invalid Entry");
}
}
}
}
Updated equals and hashCode
public boolean equals(Object obj)
{
if(obj==null)
return false;
if(obj==this)
return true;
if(obj.getClass() != getClass())
return false;
Zombie zomb = (Zombie)obj;
if(zomb.getZAge().equals(zAge) && zomb.getZType().equals(zType) && zomb.getZName().equals(zName))
return true;
else
return false;
}
public int hashCode() { return 0; }
I know that because you are trying to learn programming you are writing your own linked list instead of using Java's LinkedList. However, there are a few things you have missed.
Your equals method should have the same signature as that in Object Zombie.equals(Object). And, the first thing it should do is return false if the argument is not a Zombie.
Whenever you write an equals method, you must also write a hashCode method. Look at most any example for details.
Never use the equals operator for Strings. Always use the equals method. Replace zomb.getZAge() == zAge with zomb.getZAge().equals(zAge).
Why is zAge a String? You can let it be some sort of number.
There's no need to put 'Z' everywhere in your class. It's in a Zombie; your readers know. At work, I have colleagues who insist on repeating class names in all their variables.
This is not good code.
public class Document {
private Long documentId;
private String documentName;
private String documentAuthor;
private Date documentPublicationDate;
// 10 more instance variables.
// Constructors, accessors, other code.
}
And then they name variables of type Document as documentA, documentB, etc. How boring, repetitious, and redundant.
1) Why would you name a variable that contains the node count 'manyNodes' instead of 'nodeCount'. If you asked some random programmer what a variable named 'manyNodes' contained, do you think they would be able to guess? What if you asked some random programmer what the variable nodeCount contained? Do you think the random programmer could even guess the type of nodeCount? What about the type of 'manyNodes'?
2) How about trying something like this:
public void add(Node<E> element)
{
if (head == null) {
head = element;
}
else {
tail.nextNode = element;
}
tail = element;
nodeCount++; //Increments Node counter
}
public class Node<E>
{
private E data;
private Node<E> nextNode;
}
public class LinkedBag<E>
{
private Node<E> head;
private Node<E> tail;
private int nodeCount;
}
//Constructor
public LinkedBag()
{
head = tail = null;
nodeCount = 0;
}

BST in Java -- search Nodes by String

I am creating a binary search tree using Nodes with MovieInfo objects as keys. MovieInfo objects are objects with three fields: ID, fullName, and shortName. The binary search tree will store information on an input text file containing every movie listed on IMDB. The insert would be based on an ID randomly associated with each movie. The search features would have a user input a String and pull up the other data of the object (shortName, ID, etc).
Now -- the errors I am having are with the findExact method.
First, no matter what my input is -- I get the message "Current Node is null" which means my starting currentNode is ALWAYS going null. The other issue is, I am not sure how to make sure my root node (the first currentNode searched for in the tree) is initialized properly. I have a feeling this might have something to do with my problem.
The other problem might lie in how I am inserting the nodes in the first place.
And for reference, the way I am testing this code/running in the text input file is IndexTester.java.
UPDATE: Okay. Everything works now. The only issue I am having now is that my findExact method seems to change the ID field of the MovieInfo class. So my search does not end up working. For example, if I input:
1568482 2 White Kids with Problems 2 White Kids with Problems
1568487 Disorient Disorient
1568488 DIY Playgrounds DIY Playgrounds
and search "disorient," the return is "1568488 Disorient Disorient" (with the ID for the "2 White Kids with Problems" object). Additionally, since the ID is taken...DIY Playgrounds can't be searched for succesfully. The insertion method works, but the findExact method is giving me issues. Any ideas as to what might be causing this change in the ID?
The MovieInfo class (separate .java file) -- can't be edited
public class MovieInfo {
public String shortName;
public String fullName;
static int ID;
public String key;
public MovieInfo(int id, String s, String f) {
ID = id;
shortName = s;
fullName = f;
}
}
BSTIndex.java -- the class in which I create the internal BST
import java.util.*;
import java.io.*;
public class BSTIndex extends MovieInfo {
public Node root;
public class Node{
public MovieInfo movie;
public Node left, right;
public Node(MovieInfo movie)
{
this.movie = movie;
//this.val = val;
//this.N = N;
}
}
public BSTIndex()
/**
* constructor to initialize the internal binary search tree.
* The data element should be an object of the type MovieInfo, described above.
*/
{
super(0, "", "");
}
public MovieInfo findExact(String key) {
return findExact(root, key);
}
private MovieInfo findExact(Node x, String key) {
if (x == null) return null;
int cmp = key.compareToIgnoreCase(x.movie.fullName);
if (cmp < 0) return findExact(x.left, key);
else if (cmp > 0) return findExact(x.right, key);
else return x.movie;
}
public void insert(MovieInfo data)
{
if (data == null) {return; }
root = insert(root, data);
}
public Node insert(Node x, MovieInfo data)
{
if (x == null) return new Node(data);
int cmp = data.ID - x.movie.ID;
if (cmp > 0 ) x.right = insert(x.right, data);
else if (cmp < 0) x.left = insert(x.left, data);
else if (cmp == 0) x.movie = data;
return x;
}
}
IndexTester.java
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class IndexTester {
// Test program
public static void main( String [ ] args ) throws FileNotFoundException
{
BSTIndex t = new BSTIndex( );
Scanner scan = new Scanner(new FileInputStream(args[0]));
long start = System.currentTimeMillis();
int i=0;
while(scan.hasNext()){
String line = scan.nextLine();
String [] fields = line.split("\t");
int id = Integer.parseInt(fields[0].trim());
String shortName = fields[1].trim();
String fullName = fields[2].trim();
MovieInfo info = new MovieInfo(id, shortName, fullName);
t.insert(info);
i++;
if(i % 10000 == 0){
System.out.println("Inserted " + i + " records.");
}
}
long end = System.currentTimeMillis();
System.out.println("Index building complete. Inserted " + i +
" records.Elapsed time = " + (end - start )/1000 + " seconds.");
Scanner input = new Scanner(System.in);
System.out.println("Enter search string, end in a '*' for
prefix search. q to quit");
while(input.hasNext()){
String search = input.nextLine().trim();
if(search.equals("q")) break;
if(search.indexOf('*')>0){
//call prefix search.
MovieInfo item = t.findPrefix(search);
if(item==null) System.out.println("Not Found");
else System.out.println(item.ID + " " + item.shortName + "
" + item.fullName);
}
else{
//call exact search, modify to return MovieInfo
MovieInfo item = t.findExact(search);
if(item==null) System.out.println("Not Found");
else System.out.println(item.ID + " " + item.shortName + "
" + item.fullName);
}
}
}
}
public class BSTIndex should not extend MovieInfo, preferably MovieInfo should extend Node.
Ok, so MovieInfo cannot be modified so I would populate the MovieInfo class with the data and set it as the nodevalue of an extended Node class.
public class BSTNode extends Node {
private BSTNode left,right;
private MovieInfo val;
public void setVal(MovieInfo val){
this.val=val;
}
public void setLeft(MovieInfo m){
left=new BSTNode(m);
}
public void setRight(MovieInfo m){
right=new BSTNode(m);
}
//override some of the Node methods
}

BinaryTree implementation in java

I have this code for BinaryTree creation and traversal
class Node
{
Integer data;
Node left;
Node right;
Node()
{
data = null;
left = null;
right = null;
}
}
class BinaryTree
{
Node head;
Scanner input = new Scanner(System.in);
BinaryTree()
{
head = null;
}
public void createNode(Node temp, Integer value)
{
Node newnode= new Node();
value = getData();
newnode.data = value;
temp = newnode;
if(head==null)
{
head = temp;
}
System.out.println("If left child exits for ("+value+") enter y else n");
if(input.next().charAt(0)=='y')
{
createNode(temp.left, value);
}
System.out.println("If right child exits for ("+value+") enter y else n");
if(input.next().charAt(0)=='y')
{
createNode(temp.right, value);
}
}
public Integer getData()
{
out.println("Enter the value to insert:");
return (Integer)input.nextInt();
}
public void print()
{
inorder(head);
}
public void inorder(Node node)
{
if(node!=null)
{
inorder(node.left);
System.out.println(node.data);
inorder(node.right);
}
else
return;
}
}
class BinaryTreeWorker
{
static BinaryTree treeObj = null;
static Scanner input = new Scanner(System.in);
public static void displaymenu()
{
int choice;
do{
out.print("\n Basic operations on a tree:");
out.print("\n 1. Create tree \n 2. Insert \n 3. Search value \n 4. print list\n Else. Exit \n Choice:");
choice = input.nextInt();
switch(choice)
{
case 1:
treeObj = createBTree();
break;
case 2:
treeObj.createNode(null, null);
break;
case 3:
//searchnode();
break;
case 4:
treeObj.print();
break;
default:
return;
}
}while(true);
}
public static BinaryTree createBTree()
{
return new BinaryTree();
}
public static void main(String[] args)
{
displaymenu();
}
}
It compiles and runs. But I think there is something wrong with the inorder traversal.
I created the below tree,
2
1 3
But it prints only 2.
I have tried solving the problem your way and I have pasted the solution below.. Though I haven't tested it thoroughly so it might fail in some edge condition.. But I have tested it for one case. Kindly let me know if it fails in some scenario. I would appreciate others help in making this answer better. I agree that this solution is not the most ideal way to code a Binary Tree but it wont hurt this way if some one is just practicing..
import java.util.Scanner;
class Node
{
Integer data;
Node left;
Node right;
Node()
{
data = null;
left = null;
right = null;
}
}
class BinaryTree
{
Node head;
Scanner input = new Scanner(System.in);
BinaryTree()
{
head = null;
}
public void createNode(Node temp,Node newnode)
{
if(head==null)
{
System.out.println("No value exist in tree, the value just entered is set to Root");
head = newnode;
return;
}
if(temp==null)
temp = head;
System.out.println("where you want to insert this value, l for left of ("+temp.data+") ,r for right of ("+temp.data+")");
char inputValue=input.next().charAt(0);
if(inputValue=='l'){
if(temp.left==null)
{
temp.left=newnode;
System.out.println("value got successfully added to left of ("+temp.data+")");
return;
}else {
System.out.println("value left to ("+temp.data+") is occupied 1by ("+temp.left.data+")");
createNode(temp.left,newnode);
}
}
else if(inputValue=='r')
{
if(temp.right==null)
{
temp.right=newnode;
System.out.println("value got successfully added to right of ("+temp.data+")");
return;
}else {
System.out.println("value right to ("+temp.data+") is occupied by ("+temp.right.data+")");
createNode(temp.right,newnode);
}
}else{
System.out.println("incorrect input plz try again , correctly");
return;
}
}
public Node generateTree(){
int [] a = new int[10];
int index = 0;
while(index<a.length){
a[index]=getData();
index++;
}
if(a.length==0 ){
return null;
}
Node newnode= new Node();
/*newnode.left=null;
newnode.right=null;*/
return generateTreeWithArray(newnode,a,0);
}
public Node generateTreeWithArray(Node head,int [] a,int index){
if(index >= a.length)
return null;
System.out.println("at index "+index+" value is "+a[index]);
if(head==null)
head= new Node();
head.data = a[index];
head.left=generateTreeWithArray(head.left,a,index*2+1);
head.right=generateTreeWithArray(head.right,a,index*2+2);
return head;
}
public Integer getData()
{
System.out.println("Enter the value to insert:");
return (Integer)input.nextInt();
}
public void print()
{
inorder(head);
}
public void inorder(Node node)
{
if(node!=null)
{
inorder(node.left);
System.out.println(node.data);
inorder(node.right);
}
else
return;
}
}
public class BinaryTreeWorker
{
static BinaryTree treeObj = null;
static Scanner input = new Scanner(System.in);
public static void displaymenu()
{
int choice;
do{
System.out.print("\n Basic operations on a tree:");
System.out.print("\n 1. Create tree \n 2. Insert \n 3. Search value \n 4. print list\n 5. generate a tree \n Else. Exit \n Choice:");
choice = input.nextInt();
switch(choice)
{
case 1:
treeObj = createBTree();
break;
case 2:
Node newnode= new Node();
newnode.data = getData();
newnode.left=null;
newnode.right=null;
treeObj.createNode(treeObj.head,newnode);
break;
case 3:
//searchnode();
break;
case 4:
System.out.println("inorder traversal of list gives follows");
treeObj.print();
break;
case 5:
Node tempHead = treeObj.generateTree();
System.out.println("inorder traversal of list with head = ("+tempHead.data+")gives follows");
treeObj.inorder(tempHead);
break;
default:
return;
}
}while(true);
}
public static Integer getData()
{
System.out.println("Enter the value to insert:");
return (Integer)input.nextInt();
}
public static BinaryTree createBTree()
{
return new BinaryTree();
}
public static void main(String[] args)
{
displaymenu();
}
}
[Update] : Updated the code to generate a binary tree using an array. This will involve less user interaction.
Best way to implement Binary Tree in Java with all the traverse types and test cases as below
package com.nitin.tree;
public class Tree
{
private Node parent;
private int data;
private int size = 0;
public Tree() {
parent = new Node(data);
}
public void add(int data) {
if (size == 0) {
parent.data = data;
size++;
} else {
add(parent, new Node(data));
}
}
private void add(Node root, Node newNode) {
if (root == null) {
return;
}
if (newNode.data < root.data) {
if (root.left == null) {
root.left = newNode;
size++;
} else {
add(root.left, newNode);
}
} else {
if (root.right == null) {
root.right = newNode;
size++;
} else {
add(root.right, newNode);
}
}
}
public int getLow() {
Node current = parent;
while (current.left != null) {
current = current.left;
}
return current.data;
}
public int getHigh() {
Node current = parent;
while (current.right != null) {
current = current.right;
}
return current.data;
}
private void in(Node node) {
if (node != null) {
in(node.left);
System.out.print(node.data + " ");
in(node.right);
}
}
private void pre(Node node) {
if (node != null) {
System.out.print(node.data + " ");
pre(node.left);
pre(node.right);
}
}
private void post(Node node) {
if (node != null) {
post(node.left);
post(node.right);
System.out.print(node.data + " ");
}
}
public void preorder() {
System.out.print("Preorder Traversal->");
pre(parent);
System.out.println();
}
public void postorder() {
System.out.print("Postorder Traversal->");
post(parent);
System.out.println();
}
public void inorder() {
System.out.print("Inorder Traversal->");
in(parent);
System.out.println();
}
private class Node {
Node left;
Node right;
int data;
public Node(int data) {
this.data = data;
}
}
public String toString() {
Node current = parent;
System.out.print("Traverse From Left ");
while (current.left != null && current.right != null) {
System.out.print(current.data + "->[" + current.left.data + " " + current.right.data + "] ");
current = current.left;
}
System.out.println();
System.out.print("Traverse From Right ");
current = parent;
while (current.left != null && current.right != null) {
System.out.print(current.data + "->[" + current.left.data + " " + current.right.data + "] ");
current = current.right;
}
return "";
}
public static void main(String af[]) {
Tree t = new Tree();
t.add(40);
t.add(25);
t.add(78);
t.add(10);
t.add(32);
t.add(50);
t.add(93);
t.add(3);
t.add(17);
t.add(30);
t.add(38);
System.out.println(t.getLow());
System.out.println(t.getHigh());
System.out.println("Size-" + t.size);
System.out.println(t);
t.inorder();
t.preorder();
t.postorder();
}
}
Your problem is in public void createNodes(Node temp, T data) function. You pass in a parameter the same name as the class variable temp. First of all I don't think you need the class variable by itself. Second of all assigning to temp in this method has only local effect - you loose the information in the temp parameter, but setting temp, will not infuence its value in the called method. I suggest you rewrite the method so that it returns the pointer to the newly created node and assign this pointer to the left and right of the local temp. That way the changes will propagate out.
another type of outputting the tree:
public void inorder()
{
inorder(root);
}
protected void visit(BSTNode<T> p)
{
System.out.println("Node: " + p.el + "Left Side:" + (p.left!=null?p.left.el:"null") +
"Right Side:" + (p.right!=null?p.right.el:"null"));
}
I've changed the BinaryTree Class as below. See the change on the the createNode method in particular.
The problem, as mentioned in the post before this, is that your reference doesn't persist when it is passed as an argument to the createNode method. That change is only local. You need to return an explicit Node reference in the method itself as you're creating the node.
public Node createNode()
{
Integer value = getData();
Node temp = new Node(value);
if(head==null)
{
head = temp;
}
System.out.println("Do you want to add left branch on node("+value+")? Enter y/n");
if(input.next().charAt(0)=='y')
{
temp.left=createNode();
}
System.out.println("Do you want to add right branch on node("+value+")? Enter y/n");
if(input.next().charAt(0)=='y')
{
temp.right=createNode();
}
return temp;
}
Here is the resulting output:
Basic operations on a tree:
1. Create tree
2. Insert
3. Search value
4. print list
Else. Exit
Choice:1
Basic operations on a tree:
1. Create tree
2. Insert
3. Search value
4. print list
Else. Exit
Choice:2
Enter the value to insert:
10
Do you want to add left branch on node(10)? Enter y/n
y
Enter the value to insert:
20
Do you want to add left branch on node(20)? Enter y/n
n
Do you want to add right branch on node(20)? Enter y/n
n
Do you want to add right branch on node(10)? Enter y/n
y
Enter the value to insert:
30
Do you want to add left branch on node(30)? Enter y/n
n
Do you want to add right branch on node(30)? Enter y/n
n
Basic operations on a tree:
1. Create tree
2. Insert
3. Search value
4. print list
Else. Exit
Choice:4
20
10
30
I hope this will be of some help to someone later (even if this is 3 years late..). I just started learning about Binary Trees today myself. I'm actually planning on using this as a base to doing more involved tasks!
I changed the createNode method so that it works:
public Node createNode(Node temp, Integer value)
{
Node newnode = new Node();
value = getData();
newnode.data = value;
temp = newnode;
if(head == null)
{
head = temp;
}
System.out.println("If left child exits for ("+value+") enter y else n");
if(input.next().charAt(0) == 'y')
{
newnode.left = createNode(newnode.left, value);
}
System.out.println("If right child exits for ("+value+") enter y else n");
if(input.next().charAt(0) == 'y')
{
newnode.right = createNode(newnode.right, value);
}
return newnode;
}

Categories

Resources