This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 4 years ago.
I'm working on a Binary Search Tree assignment, and I was testing what I thought was the finished product when I saw that when I added a number to the tree and then tried to check it's predecessor/successor (by putting it into an array using in order traverse and then checking the index before/after it) it just...didn't work. Any time I try to check the predecessor/successor of a value I just put in the middle of the tree, it wigs out with an ArrayIndexOutOfBoundsException. Important note is that simply printing out using inordertraverse (called printInOrder in the code) works perfectly.
Since printing the inorder traverse works, I can assume my tree isn't the problem. The only other thing is the array, right? Am I missing something obvious?
Here's the code!
public class BST implements BSTInterface
{
//Variables/Fields
private BNode root;
//Constructors
public BST(int data)
{
root = new BNode(data);
}
//Public Methods
public boolean add(int data)
{
if(!contains(data))
{
root = addEntry(root, data);
return true;
}
else
return false;
}
public boolean contains(int data)
{
return containsNode(root, data);
}
public boolean remove(int data)
{
if(contains(data))
{
root = deleteNode(root, data);
return true;
}
else
return false;
}
public int[] toArray()
{
int[] output = new int[root.numNodes()];
inorderTraverse(output, 0, root);
return output;
}
public void printInOrder()
{
printIn(root);
}
public void printPreOrder()
{
printPre(root);
}
public void printPostOrder()
{
printPost(root);
}
//Private methods/classes
private class BNode
{
private int data;
private BNode leftChild;
private BNode rightChild;
public BNode(int data)
{
this.data = data;
leftChild = null;
rightChild = null;
}
public int getData()
{
return data;
}
public void setData(int newData)
{
data = newData;
}
public BNode getLeftChild()
{
return leftChild;
}
public BNode getRightChild()
{
return rightChild;
}
public void setRightChild(BNode node)
{
rightChild = node;
}
public void setLeftChild(BNode node)
{
leftChild = node;
}
public int numNodes()
{
int leftNum = 0;
int rightNum = 0;
if(leftChild != null)
leftNum = leftChild.numNodes();
if(rightChild != null)
rightNum = rightChild.numNodes();
return 1+leftNum+rightNum;
}
}
private BNode addEntry(BNode current, int data)
{
if(current == null)
return new BNode(data);
if(data < current.getData())
current.setLeftChild(addEntry(current.getLeftChild(), data));
else if(data > current.getData())
current.setRightChild(addEntry(current.getRightChild(), data));
return current;
}
private boolean containsNode(BNode current, int entry)
{
if(current == null)
return false;
if(entry == current.getData())
return true;
if(entry < current.getData())
return containsNode(current.getLeftChild(), entry);
else
return containsNode(current.getRightChild(), entry);
}
private BNode deleteNode(BNode current, int data)
{
if(current == null)
return null;
if(data == current.getData())
{
if(current.getLeftChild() == null && current.getRightChild() == null) //No children
return null;
if(current.getRightChild() == null) //Only right child
return current.getLeftChild();
if(current.getLeftChild() == null) //Only left child
return current.getRightChild();
int smallestChild = findSmallest(current.getRightChild());
current.setData(smallestChild);
current.setRightChild(deleteNode(current.getRightChild(), smallestChild));
return current;
}
if(data < current.getData())
{
current.setLeftChild(deleteNode(current.getLeftChild(), data));
return current;
}
else
current.setRightChild(deleteNode(current.getRightChild(), data));
return current;
}
private int findSmallest(BNode root)
{
return root.getLeftChild() == null ? root.getData() : findSmallest(root.getLeftChild());
}
private void inorderTraverse(int[] array, int count, BNode node)
{
if(node != null)
{
inorderTraverse(array, count, node.getLeftChild());
array[count] = node.getData();
count++;
inorderTraverse(array, count, node.getRightChild());
}
}
private void printIn(BNode node)
{
if(node != null)
{
printIn(node.getLeftChild());
System.out.print(node.getData() + " ");
printIn(node.getRightChild());
}
}
private void printPre(BNode node)
{
if(node != null)
{
System.out.print(node.getData() + " ");
printPre(node.getLeftChild());
printPre(node.getRightChild());
}
}
private void printPost(BNode node)
{
if(node != null)
{
printPost(node.getLeftChild());
printPost(node.getRightChild());
System.out.print(node.getData() + " ");
}
}
}
along with the driver program:
import java.util.Scanner;
public class BSTDemoReel
{
public static void main(String[] args)
{
System.out.println("This search tree only handles integers! Thanks in advance!\n\n");
Scanner keyboard = new Scanner(System.in);
//Variables
String input;
String choice = "";
int num;
int index;
boolean found;
//Starting
System.out.println("Please enter the initial sequence of values:\n");
input = keyboard.nextLine();
String[] splitInput = input.split(" ");
int[] intInputArray = new int[splitInput.length];
for(int count = 0; count < splitInput.length; count++)
{
intInputArray[count] = Integer.parseInt(splitInput[count]);
}
BST searchTree = new BST(intInputArray[0]);
for(int count = 1; count < intInputArray.length; count++)
{
searchTree.add(intInputArray[count]);
}
System.out.print("Pre-order: ");
searchTree.printPreOrder();
System.out.println();
System.out.print("In-order: ");
searchTree.printInOrder();
System.out.println();
System.out.print("Post-order: ");
searchTree.printPostOrder();
System.out.println();
//Menu
while(!choice.equals("E"))
{
System.out.print("Command? ");
choice = keyboard.next();
choice = choice.toUpperCase();
switch(choice)
{
case "I": num = keyboard.nextInt();
if(searchTree.contains(num))
System.out.println(num + " already exists. Please try again.");
else
{
searchTree.add(num);
System.out.print("In-order: ");
searchTree.printInOrder();
System.out.println();
}
break;
case "D": num = keyboard.nextInt();
if(!searchTree.contains(num))
System.out.println(num + " does not exist. Please try again.");
else
{
searchTree.remove(num);
System.out.print("In-order: ");
searchTree.printInOrder();
System.out.println();
}
break;
case "P": num = keyboard.nextInt();
if(searchTree.contains(num))
{
int[] array = searchTree.toArray();
index = 0;
found = false;
while(!found)
{
if(num == array[index])
found = true;
else
index++;
}
if(index != 0)
System.out.println(array[index-1]);
else
System.out.println("That was the first one!");
}
else
System.out.println(num + " does not exist! Please try again!");
break;
case "S": num = keyboard.nextInt();
if(searchTree.contains(num))
{
int[] array = searchTree.toArray();
index = 0;
found = false;
while(!found)
{
if(num == array[index])
found = true;
else
index++;
}
if(index != array.length-1)
System.out.println(array[index+1]);
else
System.out.println("That was the last one!");
}
else
System.out.println(num + " does not exist! Please try again!");
break;
case "E": System.out.println("Was a tricky one! Thanks for playing ;P");
break;
case "H": System.out.println("I Insert a value\n" +
"D Delete a value\n" +
"P Find predecessor\n" +
"S Find successor\n" +
"E Exit the program\n" +
"H Display this message");
break;
default: System.out.println("Invalid command. Type H for help.");
break;
}
}
keyboard.close();
}
}
If you add a couple of lines of code to print out the array returned by searchTree.toArray() before you enter the while loop that examines the array to find the value specified with the P or S commands then you'll see the cause of the problem. The array is not filled in correctly. The desired value might not be present in the array, which means that found will never become True and the while loop will continue to increment index until it exceeds the size of the array and triggers the exception that you're seeing.
Since the array is supposed to be populated by inorderTraverse(), this suggests that that function isn't doing its job correctly. The reason why it is misbehaving is that its inner recursive calls to itself do not modify the value of the count variable for the caller. count is a simple int variable, therefore the count++ statement inside the recursive call does not affect the value of count in the calling function.
Your best options are either to change inorderTraverse() so that it returns the index of the array element that should be filled in next, or change count to be an Object that contains an int member whose updated value will be visible to the caller after it has been incremented inside the recursively called function.
Since this is an assignment I'm not going to show a corrected version of the program. The change is small, so given what you've done so far I expect that you won't have much trouble making it work.
BTW, your program is missing implementations of printIn(), printPre() and printPost(). They're not hard to write, but it's an extra hurdle for anyone who might have been interested in helping you tackle the problem. That might be at least part of the reason why no-one else has offered an answer yet. The easier you make it for people to reproduce the problem, the more likely it is that you'll get answers.
Related
As the title suggests, I am currently trying to construct a binary tree wherein user inputs are inserted in in-level order. Almost all of the tutorials and implementations in Java that I've read uses a sorted method of insertion.
I've tried gfg's method, but it uses queues, which resulted me being graded 0.
gfg method:
void addData(int data) {
Node newNode = new Node(data);
if (root == null) {
root = newNode;
} else {
Queue<Node> queue = new LinkedList<>();
queue.add(root);
while (true) {
Node node = queue.remove();
if (node.left != null && node.right != null) {
queue.add(node.left);
queue.add(node.right);
}
else {
if (node.left == null) {
node.left = newNode;
queue.add(node.left);
} else {
node.right = newNode;
queue.add(node.right);
}
break;
}
}
}
}
Input: 1 2 3 4 5 6 7
Output (In-order): 4 2 5 1 6 3 7 (Correct, but as mentioned it uses queues)
The insertion that I understand w/o queues (but this one sorts user input):
private Node insertNode(Node current, int data) {
if (current == null) {
return new Node(data);
}
if (data < current.data) {
current.left = insertNode(current.left, data);
}
else if (data > current.data) {
current.right = insertNode(current.right, data);
}
else {
return current;
}
return current;
}
public void addNode(int data) {
root = insertNode(root, data);
}
Input: 1 2 3 4 5 6 7
Output (In-Order): 1 2 3 4 5 6 7
To note, yes, I've also tried to implement gfg's method to what I understand. But I personally cannot make it make sense? I'm really stuck.
Edit:
The whole code:
import java.util.Scanner;
public class BinaryTree {
static class Node {
int data;
Node left;
Node right;
Node(int data) {
this.data = data;
right = left = null;
}
}
public static class treeBinary {
Node root;
treeBinary() {
root = null;
}
private Node insertNode(Node current, int data) {
if (current == null) {
return new Node(data);
}
if (data < current.data) {
current.left = insertNode(current.left, data);
}
else if (data > current.data) {
current.right = insertNode(current.right, data);
}
else {
return current;
}
return current;
}
public void addNode(int data) {
root = insertNode(root, data);
}
public void inorderPrint(Node node) {
if (node != null) {
inorderPrint(node.left);
System.out.print(" " + node.data);
inorderPrint(node.right);
}
}
void inorderPrint() {
inorderPrint(root);
}
public void preorderPrint(Node node) {
if (node != null) {
System.out.print(" " + node.data);
preorderPrint(node.left);
preorderPrint(node.right);
}
}
void preorderPrint() {
preorderPrint(root);
}
public void postorderPrint(Node node) {
if (node != null) {
postorderPrint(node.left);
postorderPrint(node.right);
System.out.print(" " + node.data);
}
}
void postorderPrint() {
postorderPrint(root);
}
}
public static void main(String[] args) {
Scanner inputUser = new Scanner(System.in);
treeBinary userBT = new treeBinary();
boolean userChoice = false;
int count = 0;
mainMenu:
do {
System.out.println("\n\n\n1 - Add Data");
System.out.println("2 - Print (In-Order)");
System.out.println("3 - Print (Pre-Order");
System.out.println("4 - Print (Post-Order)");
System.out.println("5 - Exit");
System.out.print("Enter your choice: ");
switch (inputUser.nextInt()) {
case 1:
System.out.print("How many will you input? ");
int x = inputUser.nextInt();
for (int i = 0; i < x; i++) {
System.out.print("Input Data " + (count+1) + ": ");
userBT.addNode(inputUser.nextInt());
count++;
}
break;
case 2:
System.out.println("The Tree in In-Order: ");
userBT.inorderPrint();
break;
case 3:
System.out.println("The Tree in Pre-Order: ");
userBT.preorderPrint();
break;
case 4:
System.out.println("The Tree in Post-Order: ");
userBT.postorderPrint();
break;
case 5:
break mainMenu;
default:
System.out.println("Invalid Input!");
}
}
while (!userChoice);
}
}
After days and hours of trying and reading. I applied the idea of balancing the tree from the user's inputs instead of inserting in comparison with the previous input data. Personally, I don't know if this is what the professor is looking for, but I'll try and try. Thanks #trincot
Here is what I've came up with, just a mishmash of everything that I've read and watched, nothing original:
public static class treeBinary {
boolean checkBal(int countSide) {
countSide = countSide + 1;
while (countSide % 2 == 0) {
countSide = countSide / 2;
}
if (countSide == 1) {
return true;
}
else {
return false;
}
}
Node insertData(Node root, int data) {
if (root == null) {
Node newNode = new Node(data);
return newNode;
}
if (root.rightSide == root.leftSide) {
root.left = insertData(root.left, data);
root.leftSide++;
}
else if (root.rightSide < root.leftSide) {
if (checkBal(root.leftSide)) {
root.right = insertData(root.right, data);
root.rightSide++;
}
else {
root.left = insertData(root.left, data);
root.leftSide++;
}
}
return root;
}
void inorderPrint(Node node) {
if (node != null) {
inorderPrint(node.left);
System.out.print(node.data + " ");
inorderPrint(node.right);
}
}
}
I'll try to refine even more to the extent of my knowledge as a learning student.
I couldn't figure out how to store the number of times a recursive method calls itself. If any one could point me in the right direction I would greatly appreciate it! Below is my code in it i have a comment on where I think I am going wrong.
package module8_auriemma_assignment;
import java.util.*;
public class fibonacciTree{
Node root;
public void addNode(int key, int num) {
Node newNode = new Node(key, num);
if (root == null) {
root = newNode;
}
else {
Node focusNode = root;
Node parent;
while (true) {
parent = focusNode;
if (key < focusNode.key) {
focusNode = focusNode.leftChild;
if (focusNode == null) {
parent.leftChild = newNode;
return;
}
}
else
{
focusNode = focusNode.rightChild;
if (focusNode == null) {
// then place the new node on the right of it
parent.rightChild = newNode;
return; // All Done
}
}
}
}
}
public static void main(String[] args) {
fibonacciTree theTree = new fibonacciTree();
Scanner input = new Scanner (System.in);
System.out.println("Please enter an index");
System.out.println("I will compute your index's Fibonacci numbers.");
System.out.println("I will compute numbers that do not exceed a billion");
int number;
int key;
key = 0;
for(number = input.nextInt(); number < 1000000; number++){
System.out.println(fibonacci(number));
theTree.addNode(key, number);
/*
I am not sure if I should be adding a new node everytime the
loop happens in the main class OR if I should be having it store
a node inside of the fibonacci method itself
*/
number++;
key++;
}
}
public static long fibonacci(int i)
{
if (i == 0) return 0;
if (i <= 2) return 1;
long fibTerm = fibonacci(i - 1) + fibonacci(i - 2);
if(fibTerm > 1000000000){
System.out.println("Number too large");
System.exit(0);
}
else{
return fibTerm;
}
return fibTerm;
}
}
.
package module8_auriemma_assignment;
class Node {
int key;
int num;
Node leftChild;
Node rightChild;
Node(int key, int num) {
this.key = key;
this.num = num;
}
#Override
public String toString() {
return num + " has the key " + key;
}
}
fibonacci(int i) keeps calling itself until it is reduced to a series of 1+1+1+1+1+1+1+1+1+1+1+...
The solution is also the number of times the method is called. If you want to know how many times it was called, look at the return value.
Here is my code to find position of a certain element. And I am using Binary tree to store my Dictionary I want to know why it shows warning for Comparable-type. I have to use this in my project where element is a string type.
public int get(Comparable element){
return getPosition(element,root);
}
private int getPosition(Comparable element, TreeNode root){
int count = 0;
if (root == null){
return -1;
}else{
Stack t = new Stack();
t.push(root);
while(!t.empty()){
TreeNode n = (TreeNode)t.pop();
if(element.compareTo(n.value)==0){
return count;
}else{
if(n.getLeftTree()!=null){
t.push(n.getLeftTree());
count++;
}
if (n.getRightTree()!= null){
t.push(n.getRightTree());
count++;
}
}
}
return -1;
}
}
The java generic typing parameters are missing <...>.
public int get(Comparable<?> element){
return getPosition(element, root);
}
private int getPosition(Comparable<?> element, TreeNode root) {
int count = 0;
if (root == null) {
return -1;
} else {
Stack<TreeNde> t = new Stack<>();
t.push(root);
while (!t.empty()) {
TreeNode n = t.pop();
if (element.compareTo(n.value) == 0) {
return count;
} else {
if (n.getLeftTree() != null) {
t.push(n.getLeftTree());
count++;
}
if (n.getRightTree() != null) {
t.push(n.getRightTree());
count++;
}
}
}
}
return -1;
}
However the algorithm seems not to be counting the leftish part of the tree upto the found element. However if position is not the index in the sorted elements, that might be okay. (I did not check the correctness, as there is no early < check.) If this was a home work assignment, "non-recursive with stack," rework a recursive version. Probably two nested loops, and a comparison on -1 and +1.
Greeting to everyone. I currently work on a program that sorting the emergency number of patients(the number that assigned by nurse when they enter the emergency room and this number determines the seriousness of their sickness too). However, if there are more than 1 patient who hold the same emergency numbers(eg: 2 patients hold emergency number 1), the one who came earlier should receive the treatment first. For this reason, I have 2 sortings, one is to sort the emergency number in ascending order and the other is to sort the time in ascending order too. But unfortunately the second sorting cannot work correctly.The following are the explanations for the type of emergency numbers:
Emergency number : 1 – Immediately life threatening
Emergency number : 2 – Urgent, but not immediately life threatening
Emergency number : 3 – Less urgent
So,now comes the coding part(Please note that this is a linkedlist)
Interface:
public interface ListInterface<T> {
public boolean add(T newEntry);
public boolean add(int newPosition, T newEntry);
public T remove(int givenPosition);
public void clear();
public boolean replace(int givenPosition, T newEntry);
public T getEntry(int givenPosition);
public boolean contains(T anEntry);
public int getLength();
public boolean isEmpty();
public boolean isFull();
}
LList class:
/**
* LList.java
* A class that implements the ADT list by using a chain of nodes,
* with the node implemented as an inner class.
*/
public class LList<T> implements ListInterface<T> {
private Node firstNode; // reference to first node
private int length; // number of entries in list
public LList() {
clear();
}
public final void clear() {
firstNode = null;
length = 0;
}
public boolean add(T newEntry) {
Node newNode = new Node(newEntry); // create the new node
if (isEmpty()) // if empty list
firstNode = newNode;
else { // add to end of nonempty list
Node currentNode = firstNode; // traverse linked list with p pointing to the current node
while (currentNode.next != null) { // while have not reached the last node
currentNode = currentNode.next;
}
currentNode.next = newNode; // make last node reference new node
}
length++;
return true;
}
public boolean add(int newPosition, T newEntry) { // OutOfMemoryError possible
boolean isSuccessful = true;
if ((newPosition >= 1) && (newPosition <= length+1)) {
Node newNode = new Node(newEntry);
if (isEmpty() || (newPosition == 1)) { // case 1: add to beginning of list
newNode.next = firstNode;
firstNode = newNode;
}
else { // case 2: list is not empty and newPosition > 1
Node nodeBefore = firstNode;
for (int i = 1; i < newPosition - 1; ++i) {
nodeBefore = nodeBefore.next; // advance nodeBefore to its next node
}
newNode.next = nodeBefore.next; // make new node point to current node at newPosition
nodeBefore.next = newNode; // make the node before point to the new node
}
length++;
}
else
isSuccessful = false;
return isSuccessful;
}
public T remove(int givenPosition) {
T result = null; // return value
if ((givenPosition >= 1) && (givenPosition <= length)) {
if (givenPosition == 1) { // case 1: remove first entry
result = firstNode.data; // save entry to be removed
firstNode = firstNode.next;
}
else { // case 2: givenPosition > 1
Node nodeBefore = firstNode;
for (int i = 1; i < givenPosition - 1; ++i) {
nodeBefore = nodeBefore.next; // advance nodeBefore to its next node
}
result = nodeBefore.next.data; // save entry to be removed
nodeBefore.next = nodeBefore.next.next; // make node before point to node after the
} // one to be deleted (to disconnect node from chain)
length--;
}
return result; // return removed entry, or
// null if operation fails
}
public boolean replace(int givenPosition, T newEntry) {
boolean isSuccessful = true;
if ((givenPosition >= 1) && (givenPosition <= length)) {
Node currentNode = firstNode;
for (int i = 0; i < givenPosition - 1; ++i) {
// System.out.println("Trace| currentNode.data = " + currentNode.data + "\t, i = " + i);
currentNode = currentNode.next; // advance currentNode to next node
}
currentNode.data = newEntry; // currentNode is pointing to the node at givenPosition
}
else
isSuccessful = false;
return isSuccessful;
}
public T getEntry(int givenPosition) {
T result = null;
if ((givenPosition >= 1) && (givenPosition <= length)) {
Node currentNode = firstNode;
for (int i = 0; i < givenPosition - 1; ++i) {
currentNode = currentNode.next; // advance currentNode to next node
}
result = currentNode.data; // currentNode is pointing to the node at givenPosition
}
return result;
}
public boolean contains(T anEntry) {
boolean found = false;
Node currentNode = firstNode;
while (!found && (currentNode != null)) {
if (anEntry.equals(currentNode.data))
found = true;
else
currentNode = currentNode.next;
}
return found;
}
public int getLength() {
return length;
}
public boolean isEmpty() {
boolean result;
if (length == 0)
result = true;
else
result = false;
return result;
}
public boolean isFull() {
return false;
}
public String toString() {
String outputStr = "";
Node currentNode = firstNode;
while (currentNode != null) {
outputStr += currentNode.data + "\n";
currentNode = currentNode.next;
}
return outputStr;
}
private class Node {
private T data;
private Node next;
private Node(T data) {
this.data = data;
this.next = null;
}
private Node(T data, Node next) {
this.data = data;
this.next = next;
}
} // end Node
} // end LList
Patient class:
public class Patient {
private int emergencyNo;
private int queueTime;
private String patientName;
private String patientIC;
private String patientGender;
private String patientTelNo;
private String patientAdd;
private String visitDate;
public Patient() {
}
public Patient(int emergencyNo, int queueTime, String patientName, String patientIC, String patientGender, String patientTelNo, String patientAdd, String visitDate)
{
this.emergencyNo = emergencyNo;
this.queueTime = queueTime;
this.patientName = patientName;
this.patientIC = patientIC;
this.patientGender = patientGender;
this.patientTelNo = patientTelNo;
this.patientAdd = patientAdd;
this.visitDate = visitDate;
}
//set methods
public void setQueueTime(int queueTime)
{
this.queueTime = queueTime;
}
public boolean setEmergencyNo(int emergencyNo)
{
boolean varEmergencyNo = true;
if (emergencyNo != 1 && emergencyNo != 2 && emergencyNo != 3)
{
varEmergencyNo = false;
System.out.println("Emergency number is in invalid format!");
System.out.println("Emergency number is either 1, 2 or 3 only!");
System.out.println("\n");
}
else
{
this.emergencyNo = emergencyNo;
}
return varEmergencyNo;
}
public boolean setPatientName(String patientName)
{
boolean varPatientName = true;
if (patientName.equals("") || patientName.equals(null))
{
varPatientName = false;
System.out.println("The patient name cannot be empty!\n");
}
else
{
this.patientName = patientName;
}
return varPatientName;
}
public boolean setPatientIC(String patientIC)
{
boolean varPatientIC = true;
if(!patientIC.matches("^[0-9]{12}$"))
{
varPatientIC = false;
System.out.println("IC is in invalid format!");
System.out.println("It must consist of 12 numbers only!\n");
}
else
{
this.patientIC = patientIC;
}
return varPatientIC;
}
public boolean setPatientGender(String patientGender)
{
boolean varPatientGender = true;
if(!patientGender.equals("F") && !patientGender.equals("f") && !patientGender.equals("M") && !patientGender.equals("m"))
{
varPatientGender = false;
System.out.println("Gender is in invalid format!");
System.out.println("It must be either 'M' or 'F' only!\n");
}
else
{
this.patientGender = patientGender;
}
return varPatientGender;
}
public boolean setPatientTelNo(String patientTelNo)
{
boolean varPatientTelNo = true;
if((!patientTelNo.matches("^01[02346789]\\d{7}$")) && (!patientTelNo.matches("^03\\d{8}$")))
{
varPatientTelNo = false;
System.out.println("Invalid phone number!");
System.out.println("It must be in the following format : 0167890990 / 0342346789!\n");
System.out.print("\n");
}
else
{
this.patientTelNo = patientTelNo;
}
return varPatientTelNo;
}
public boolean setPatientAdd(String patientAdd)
{
boolean varPatientAdd = true;
if (patientAdd.equals("") || patientAdd.equals(null))
{
varPatientAdd = false;
System.out.println("The patient address cannot be empty!\n");
}
else
{
this.patientAdd = patientAdd;
}
return varPatientAdd;
}
public void setVisitDate(String visitDate)
{
this.visitDate = visitDate;
}
//get methods
public int getQueueTime()
{
return this.queueTime;
}
public int getEmergencyNo()
{
return this.emergencyNo;
}
public String getPatientName()
{
return this.patientName;
}
public String getPatientIC()
{
return this.patientIC;
}
public String getPatientGender()
{
return this.patientGender;
}
public String getPatientTelNo()
{
return this.patientTelNo;
}
public String getPatientAdd()
{
return this.patientAdd;
}
public String getVisitDate()
{
return this.visitDate;
}
#Override
public String toString()
{
return (this.emergencyNo + "\t\t" + this.patientName + "\t\t" + this.patientIC +
"\t\t" + this.patientGender + "\t\t" + this.patientTelNo + "\t\t" + this.patientAdd + "\t\t" + this.visitDate);
}
public String anotherToString()
{
return (this.emergencyNo + "\t\t\t\t\t\t" + this.patientName + "\t\t\t " + this.visitDate);
}
}
EmergencyCmp(Comparator)--->use for sorting the emergency numbers of the patients
import java.util.Comparator;
public class EmergencyCmp implements Comparator<Patient>
{
#Override
public int compare(Patient p1, Patient p2)
{
if(p1.getEmergencyNo() > p2.getEmergencyNo())
{
return 1;
}
else
{
return -1;
}
}
}
QueueCmp(Comparator)--->use for sorting the arrival time of the patients
import java.util.Comparator;
public class QueueCmp implements Comparator<Patient>
{
#Override
public int compare(Patient p1, Patient p2)
{
if(p1.getQueueTime() > p2.getQueueTime())
{
return 1;
}
else
{
return -1;
}
}
}
Main function:
import java.util.Calendar;
import java.util.Scanner;
import java.util.Arrays;
import java.util.*;
public class DSA {
public DSA() {
}
public static void main(String[] args) {
//patient's attributes
int emergencyNo;
int queueTime;
String patientName;
String patientIC;
String patientGender;
String patientTelNo;
String patientAdd;
String visitDate;
//counter
int j = 0;
int x = 0;
int y = 0;
int z = 0;
int count1 = 0;
int count2 = 0;
int count3 = 0;
int countEnteredPatient = 1;
int totalCount = 0;
//calendar
int nowYr, nowMn, nowDy, nowHr, nowMt, nowSc;
//others
boolean enterNewPatient = true;
String continueInput;
boolean enterNewPatient1 = true;
String continueInput1;
boolean continueEmergencyNo;
Scanner scan = new Scanner(System.in);
ListInterface<Patient> patientList = new LList<Patient>();
ListInterface<Patient> newPatientList = new LList<Patient>();
Patient[] patientArr1 = new Patient[10000];
Patient[] patientArr2 = new Patient[10000];
Patient[] patientArr3 = new Patient[10000];
Patient tempoPatient;
do{
//do-while loop for entering new patient details after viewing patient list
System.out.println("Welcome to Hospital Ten Stars!\n");
do{
//do-while loop for entering new patient details
System.out.println("Entering details of patient " + countEnteredPatient);
System.out.println("===================================\n");
Calendar calendar = Calendar.getInstance();
nowYr = calendar.get(Calendar.YEAR);
nowMn = calendar.get(Calendar.MONTH);
nowDy = calendar.get(Calendar.DAY_OF_MONTH);
nowHr = calendar.get(Calendar.HOUR);
nowMt = calendar.get(Calendar.MINUTE);
nowSc = calendar.get(Calendar.SECOND);
queueTime = calendar.get(Calendar.MILLISECOND);
visitDate = nowDy + "/" + nowMn + "/" + nowYr + ", " + nowHr + ":" + nowMt + ":" + nowSc;
//input emergency number
do{
tempoPatient = new Patient();
continueEmergencyNo = false;
int EmergencyNoOption;
try
{
do{
System.out.print("Please select 1 – Immediately life threatening, 2 – Urgent, but not immediately life threatening or 3 – Less urgent(Eg: 1) : ");
EmergencyNoOption = scan.nextInt();
scan.nextLine();
System.out.print("\n");
}while(tempoPatient.setEmergencyNo(EmergencyNoOption) == false);
}
catch(InputMismatchException ex)
{
System.out.print("\n");
System.out.println("Invalid input detected.");
scan.nextLine();
System.out.print("\n");
continueEmergencyNo = true;
}
}while(continueEmergencyNo);
//input patient name
do{
System.out.print("Patient name(Eg: Christine Redfield) : ");
patientName = scan.nextLine();
System.out.print("\n");
}while(tempoPatient.setPatientName(patientName) == false);
//input patient ic no
do{
System.out.print("Patient IC number(Eg: 931231124567) : ");
patientIC = scan.nextLine();
System.out.print("\n");
}while(tempoPatient.setPatientIC(patientIC) == false);
//input patient gender
do{
System.out.print("Patient gender(Eg: M) : ");
patientGender = scan.nextLine();
System.out.print("\n");
}while(tempoPatient.setPatientGender(patientGender) == false);
//input patient tel. no
do{
System.out.print("Patient tel.No(without'-')(Eg: 0162345678/0342980123) : ");
patientTelNo = scan.nextLine();
System.out.print("\n");
}while(tempoPatient.setPatientTelNo(patientTelNo) == false);
//input patient address
do{
System.out.print("Patient address(Eg: 4-C9 Jln Besar 123, Taman Besar, 56000 Kuala Lumpur) : ");
patientAdd = scan.nextLine();
System.out.print("\n");
}while(tempoPatient.setPatientAdd(patientAdd) == false);
tempoPatient.setQueueTime(queueTime);
tempoPatient.setVisitDate(visitDate);
patientList.add(tempoPatient);
//decide whether want to enter a new patient or not
do{
System.out.print("Do you want to enter another new patient?(Eg: Y/N) : ");
continueInput = scan.nextLine();
if(continueInput.equals("Y") || continueInput.equals("y"))
{
enterNewPatient = true;
System.out.print("\n");
}
else if(continueInput.equals("N") || continueInput.equals("n"))
{
enterNewPatient = false;
}
else
{
System.out.println("\n");
System.out.println("Please enter Y/N only.\n");
}
}while(!continueInput.equals("Y") && !continueInput.equals("y") && !continueInput.equals("N") && !continueInput.equals("n"));
countEnteredPatient++;
}while(enterNewPatient); //end do-while loop for entering new patient details
System.out.println("\nWaiting list of patient will be displayed soon.\n");
try{
Thread.sleep(1000);
}
catch (Exception e)
{
}
System.out.println("Waiting list of patients");
System.out.println("========================\n");
System.out.println("Number\t\tEmergency number\t\tPatient name\t\t ArrivalTime");
System.out.println("============================================================================");
for(int i = 1; i <= patientList.getLength(); i++)
{
System.out.println(i + "\t\t\t" + patientList.getEntry(i).anotherToString());
}
do{
System.out.print("\nSo, now do you want to enter another new patient?(Eg: Y/N) : ");
continueInput1 = scan.nextLine();
if(continueInput1.equals("Y") || continueInput1.equals("y"))
{
enterNewPatient1 = true;
System.out.print("\n");
}
else if(continueInput1.equals("N") || continueInput1.equals("n"))
{
enterNewPatient1 = false;
}
else
{
System.out.println("\n");
System.out.println("Please enter Y/N only.\n");
}
}while(!continueInput1.equals("Y") && !continueInput1.equals("y") && !continueInput1.equals("N") && !continueInput1.equals("n"));
}while(enterNewPatient1);//end do-while loop for entering new patient details after viewing patient list
System.out.println("\nNow rearranging the list based on the seriouness and their arrival time.");
try{
Thread.sleep(1000);
}
catch (Exception e)
{
}
//create an unsorted array
Patient[] tempoPatientArr = new Patient[patientList.getLength()];
//copy the contents of patientList into tempoPatientArr
for(int i = 1; i <= patientList.getLength(); i++ )
{
tempoPatientArr[i-1] = patientList.getEntry(i);
}
//sort tempoPatientArr
Arrays.sort(tempoPatientArr, new EmergencyCmp());
//the above part until this comment line does not have problem
//check the emergency no and then categorise accordingly
for(int i = 0; i < tempoPatientArr.length; i++)
{
if(tempoPatientArr[i].getEmergencyNo() == 1)
{
patientArr1[x] = tempoPatientArr[i];
x++;
}
else if(tempoPatientArr[i].getEmergencyNo() == 2)
{
patientArr2[y] = tempoPatientArr[i];
y++;
}
else if(tempoPatientArr[i].getEmergencyNo() == 3)
{
patientArr3[z] = tempoPatientArr[i];
z++;
}
}
//to check how many !null elements by using count for 3 sub-arrays
for(int i = 0; i < patientArr1.length; i++)
{
if(patientArr1[i] != null)
{
count1++;
}
else
{
break;
}
}
for(int i = 0; i < patientArr2.length; i++)
{
if(patientArr2[i] != null)
{
count2++;
}
else
{
break;
}
}
for(int i = 0; i < patientArr3.length; i++)
{
if(patientArr3[i] != null)
{
count3++;
}
else
{
break;
}
}
//new array with elimination of null values
Patient[] newPatientArr1 = new Patient[count1];
Patient[] newPatientArr2 = new Patient[count2];
Patient[] newPatientArr3 = new Patient[count3];
//copy the contents of old sub arrays(the arrays with null values) into the new sub arrays(without null values)
for(int i = 0; i < newPatientArr1.length; i++)
{
newPatientArr1[i] = patientArr1[i];
}
for(int i = 0; i < newPatientArr2.length; i++)
{
newPatientArr2[i] = patientArr2[i];
}
for(int i = 0; i < newPatientArr3.length; i++)
{
newPatientArr3[i] = patientArr3[i];
}
totalCount = count1 + count2 + count3;
//array that used to combine all the sub-arrays
Patient[] newPatientArr = new Patient[totalCount];
//sort all sub new arrays
Arrays.sort(newPatientArr1, new QueueCmp());
Arrays.sort(newPatientArr2, new QueueCmp());
Arrays.sort(newPatientArr3, new QueueCmp());
//combine the contents of sub new arrays into the newPatientArr array
do{
for (int i = 0; i < count1; i++)
{
newPatientArr[j] = newPatientArr1[i];
j++;
}
for (int b = 0; b < count2; b++)
{
newPatientArr[j] = newPatientArr2[b];
j++;
}
for (int c = 0; c < count3; c++)
{
newPatientArr[j] = newPatientArr3[c];
j++;
}
}while(j < totalCount);
//relink the nodes
for(int i = 0; i < newPatientArr.length; i++)
{
newPatientList.add(newPatientArr[i]);
}
System.out.println("\nSorted waiting list of patients");
System.out.println("===============================\n");
System.out.println("Number\t\tEmergency number\t\tPatient name\t\t ArrivalTime");
System.out.println("============================================================================");
for(int i = 1; i <= newPatientList.getLength(); i++)
{
System.out.println(i + "\t\t\t" + newPatientList.getEntry(i).anotherToString());
}
}
}
Interface and LList class definitely do not have problems. So everyone can skip the 2 parts.
For the main function, I have a comment like this:
//the above part until this comment line does not have problem
When you all see the comment, that means the previous code does not have problem and you all may skip it and below is an attachment of the result that I got earlier:
So, from the picture you all can see that the sorting of arrival time is not correct. I hope that I can know why does this problem occurs since I cannot figure it out by myself. Thanks to all of you first.
So, after taking the advice of #Scott Hunter, I have made the following modification to the EmergencyCmp:
#Override
public int compare(Patient p1, Patient p2)
{
int value = 0;
if(p1.getEmergencyNo() > p2.getEmergencyNo())
{
value = 1;
}
else if(p1.getEmergencyNo() < p2.getEmergencyNo())
{
value = -1;
}
else if(p1.getEmergencyNo() == p2.getEmergencyNo())
{
if(p1.getQueueTime() > p2.getQueueTime())
{
return 1;
}
else
{
return -1;
}
}
return value;
}
However, the time sorting still produce a wrong result.
As I understand it (which I may not; you provided a LOT of extraneous stuff), it looks like you are trying to perform 2 distinct sorts, one after the other, such that the second is undoing the work of the first. Instead, you should define a single Comparator which compares emergency numbers and, only if they are the same, compares arrival times.
I am working on a Binary Search Tree for class and have most of my code implemented (I think) correctly, although if I attempt to delete the root node, nothing happens.
Does anyone see a problem with my code?
public class BinarySearchTree {
private Node root;
private int size = 0;
public BinarySearchTree(){
root = null;
}
public BinarySearchTree create(){
BinarySearchTree tree = new BinarySearchTree();
return tree;
}
public int size(){
return size;
}
public Node getRoot(){
System.out.println("root: " + root.getData());
return root;
}
public void insert(String s){
root = insertHelper(root, s.toLowerCase());
size++;
}
private Node insertHelper(Node n, String s){
if(n == null){
//root is null, make it a new node
n = new Node(s);
} else if(s.compareTo(n.getData()) < 0){
//string is alphabetically less than root
n.setLeft(insertHelper(n.getLeft(), s));
n.getLeft().setParent(n);
} else{
//string is alphabetically greater than root
n.setRight(insertHelper(n.getRight(), s));
n.getRight().setParent(n);
}
return n;
}
public void delete(String s){
deleteHelper(root, s.toLowerCase());
}
private void deleteHelper(Node n, String s){
if(n == null){
//nothing to delete
return;
}
//found node to delete
else if(s.equals(n.getData())){
System.out.println("DELETED: " + n.getData());
//check for left subtree
//if null, replace node-to-be-deleted with
//right subtree
if(n.getLeft() == null){
replace(n, n.getRight());
}
//check for right subtree
//if null, replace node-to-be-deleted with
//left subtree
else if(n.getRight() == null){
replace(n, n.getLeft());
}
//if it has two subtrees, find minimum value of the
//right tree and swap the node-to-be-deleted's data with
//the minimum node's data
else{
Node min = n.getRight();
while(min.getLeft() != null){
min = min.getLeft();
}
//replace with right and reset pointers
if(min.getParent() != n){
replace(min, min.getRight());
min.setRight(n.getRight());
min.getRight().setParent(min);
}
//replace with left and reset pointers
else{
replace(n, min);
min.setLeft(n.getLeft());
min.getLeft().setParent(min);
}
}
}
//if it hasn't been found, recurse left
else if(s.compareTo(n.getData()) < 0){
deleteHelper(n.getLeft(), s);
}
//then, recurse right
else{
deleteHelper(n.getRight(), s);
}
}
private void replace(Node x, Node y){
//if x is the root, set root to y
if(x.getParent() == null){
root = y;
}
//if x is a left child, set it's parent's left child to y
else if(x == x.getParent().getLeft()){
x.getParent().setLeft(y);
}
//if x is a right child, set it's parent's right child to y
else{
x.getParent().setRight(y);
}
//if y is not null, set y's parent to be x's parent
if(y != null){
y.setParent(x.getParent());
}
}
public void destroy(){
//wipe out the tree
root = null;
size = 0;
}
public boolean find(String s){
return findHelper(root, s.toLowerCase());
}
public boolean findHelper(Node n, String s){
if(n == null){
System.out.println("Sorry, " + s + " is not in here.");
return false;
}
if(s.equals(n.getData())){
System.out.println(s + " is in the tree.");
return true;
} else if(s.compareTo(n.getData()) < 0){
return findHelper(n.getLeft(), s);
} else{
return findHelper(n.getRight(), s);
}
}
}
public class SearchDriver {
/**
* #param args
*/
public static void main(String[] args) {
SearchDriver me = new SearchDriver();
me.doIt();
}
public void doIt(){
BinarySearchTree tree = new BinarySearchTree();
tree.insert("marry");
tree.insert("alpha");
tree.insert("gamma");
tree.insert("delta");
tree.insert("epsilon");
tree.insert("zeta");
tree.insert("eta");
tree.insert("theta");
tree.insert("iota");
tree.insert("kappa");
tree.insert("lambda");
tree.insert("beta");
tree.insert("nu");
tree.insert("xi");
tree.insert("omicron");
tree.insert("pi");
tree.insert("rho");
tree.insert("sigma");
tree.insert("tau");
tree.insert("upsilon");
tree.insert("phi");
tree.insert("chi");
tree.insert("psi");
tree.insert("omega");
tree.printInOrder();
tree.delete("psi");
tree.printInOrder();
tree.delete("marry");
tree.printInOrder();
tree.printPostOrder();
}
}
Let me help you:
Build your program in an IDE
Set a breakpoint at the start of your main method
Start your program in a debugger
Step through the code with the scenario where root is being deleted
If you cannot solve this problem with the advice given above, put a comment in this question as to what specifically you were stuck on. If you don't take the time now to learn these skills, it will haunt you forever and ever in your programming profession.
The problem is with:
if (min.getParent() != n) {
replace(min, min.getRight());
min.setRight(n.getRight());
min.getRight().setParent(min);
}
This is never replacing n with min so root is never being set to its new value.