Java Binary Tree entered in a specific order - java
I am trying to complete an assignment where I need to write a Java program to take a string from the command line, and implement it as a Binary Tree in a specific order, then get the depth of the binary tree.
For example: "((3(4))7((5)9))"
would be entered as a tree with 7 as the root, 3 and 9 as the children, and 4 as a right child of 3, and 5 as a left child of 9.
My code is below.. The problem I am having is that, because I am basing my checks off of finding a right bracket, I am unsure how to get the elements correctly when they are not directly preceding the brackets, such as the 3 in the above string. Any direction would be greatly appreciated..
class Node {
int value;
Node left, right;
}
class BST {
public Node root;
// Add Node to Tree
public void add(int n) {
if (root == null) {
root = new Node( );
root.value = n;
}
else {
Node marker = root;
while (true) {
if (n < marker.value) {
if (marker.left == null) {
marker.left = new Node( );
marker.left.value = n;
break;
} else {
marker = marker.left;
}
} else {
if (marker.right == null) {
marker.right = new Node( );
marker.right.value = n;
break;
} else {
marker = marker.right;
}
}
}
}
} // End ADD
//Find Height of Tree
public int height(Node t) {
if (t.left == null && t.right == null) return 0;
if (t.left == null) return 1 + height(t.right);
if (t.right == null) return 1 + height(t.left);
return 1 + Math.max(height(t.left), height(t.right));
} // End HEIGHT
// Check if string contains an integer
public static boolean isInt(String s) {
try {
Integer.parseInt(s);
}
catch(NumberFormatException e) {
return false;
}
return true;
} // End ISINT
public int elementCount(String[] a) {
int count = 0;
for (int i = 0; i < a.length; i++) {
if (isInt(a[i])) count++;
}
return count;
}
} // End BST Class
public class Depth {
public static void main(String[] args) {
String[] a = args[0].split(" ");
BST tree = new BST();
int[] bcount = new int[10];
int[] elements = new int[10];
int x = 0, bracketcount = 0;
// Display entered string
System.out.print("Entered Format: ");
for (int j=0; j < a.length; j++) {
System.out.print(a[j]);
}
for (int i=0; i < a.length; i++) {
char c = a[i].charAt(0);
switch (c)
{
case '(':
bracketcount++;
break;
case ')':
if (isInt(a[i-1])) {
bcount[x] = bracketcount--;
elements[x++] = Integer.parseInt(a[i-1]);
}
break;
case '1':
case '7':
default : // Illegal character
if ( (a[i-1].charAt(0) == ')') && (a[i+1].charAt(0) == '(') ) {
bcount[x] = bracketcount;
elements[x++] = Integer.parseInt(a[i]);
}
break;
}
}
System.out.println("\nTotal elements: " + tree.elementCount(a));
// Display BracketCounts
for (int w = 0; w < x; w++) {
System.out.print(bcount[w] + " ");
}
System.out.println(" ");
// Display Elements Array
for (int w = 0; w < x; w++) {
System.out.print(elements[w] + " ");
}
System.out.println("\nDepth: " + tree.height(tree.root));
// Build the tree
for (int y = 0; y < x-1; y++) {
for (int z = 1; z < tree.height(tree.root); z++) {
if (bcount[y] == z) {
tree.add(elements[y]);
}
}
}
} // End Main Function
public static boolean isInt(String s) {
try {
Integer.parseInt(s);
}
catch(NumberFormatException e) {
return false;
}
return true;
}
} // End Depth Class
I would do a couple of statements to get access to a tree with that kind of shape:
For input string : input= "((3(4))7((5)9))"
You could do :
public class Trial {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String input = "((3(4))7((5)9))";
String easier = input.replaceAll("\\(\\(", "");
String evenEasier = easier.replaceAll("\\)\\)", "");
System.out.println(evenEasier);
int firstVal = Integer.parseInt(evenEasier.substring(0, 1));
int firstBracketVal = Integer.parseInt(evenEasier.substring(2, 3));
int middleVal = Integer.parseInt(evenEasier.substring(3, 4));
int secondBracketVal = Integer.parseInt(evenEasier.substring(4,5));
int lastVal = Integer.parseInt(evenEasier.substring(6));
System.out.println("First Val:"+firstVal);
System.out.println("First bracket Val:"+firstBracketVal);
System.out.println("Middle Val:"+middleVal);
System.out.println("Second Bracket Val:"+secondBracketVal);
System.out.println("Last Val:"+lastVal);
}
}
This however would only ever work for entries in that specific format, if that were to change, or the length of the input goes up - this would work a bit or break.....If you need to be able to handle more complicated trees as input in this format a bit more thought would be needed on how to best handle and convert into your internal format for processing.
pseudocode:
function getNode(Node)
get one char;
if (the char is "(")
getNode(Node.left);
get one char;
end if;
Node.value = Integer(the char);
get one char;
if (the char is "(")
getNode(Node.right);
get one char;
end if;
//Now the char is ")" and useless.
end function
Before calling this function, you should get a "(" first.
In this method, the framwork of a Node in string is "[leftchild or NULL] value [rightchild or NULL])".
"("is not belong to the Node, but ")" is.
Related
Narrow down chromatic number to range
I am required to write a program that takes in an input file (which represents a graph) and outputs the chromatic number along with the vertices colors. I wrote a program that does this successfully, however I am given a large input file and the program runs indefinitely. I need to make the program narrow down the chromatic number to a range of ten values. Can anyone give me some advice as to how I can accomplish this. I will post my code below for reference. Any help would be appreciated. Thanks! import java.util.*; import java.io.*; public class chromatic_num { public static int n; public static int q[]; public static int matrix[][]; public static List<Integer> list; public static void main(String[] args) throws IOException { //reads input from file BufferedReader br; try { br = new BufferedReader(new InputStreamReader(new FileInputStream("file1.txt"))); } catch (FileNotFoundException e) { throw new RuntimeException(); } String line; boolean readFirstLine = false; // new array list to store input list = new ArrayList<Integer>(); // read file line by line while ((line = br.readLine()) != null) { // prints content String[] toks = line.split(" "); if (readFirstLine) { list.add(Integer.parseInt(toks[0])); list.add(Integer.parseInt(toks[1])); } else { readFirstLine = true; n = Integer.parseInt(toks[0]); } } // finds max edges n = Collections.max(list); // for adjacency matrix matrix = new int[n][n]; // constructs adj. matrix int count = 0; Integer v1 = 0, v2 = 0; for (Integer v : list) { if (count % 2 == 0) { v1 = v - 1; } else { v2 = v - 1; matrix[v1][v2] = 1; matrix[v2][v1] = 1; } count++; } // new array to store colors q = new int[n]; chromatic_num chromatic = new chromatic_num(); //print solution to screen System.out.println(chromatic.color()); for (int i = 0; i < n; i++) { System.out.println("" + (i + 1) + " " + q[i]); } //print solution to file try { System.setOut(new PrintStream(new FileOutputStream("chromatic_num.txt"))); } catch (FileNotFoundException e) { throw new RuntimeException(); } System.out.println(chromatic.color()); for (int i = 0; i < n; i++) { System.out.println("" + (i + 1) + " " + q[i]); } br.close(); } //color G using minimum number of colors, returns chromatic number public int color() { //for (int t = 0 for (int i = 1; i <= n; i++) { //if G can be colored using i colors starting at vertex 0 //System.out.println("colored using " + i + " colors starting at vertex 1"); if (color(0,i)) { //chromatic number is i, return it return i; } else { for (int j = 0; j < n; j++) { q[j] = 0; } } } return 0; } //colors G using m colors starting at vertex v public boolean color(int v, int m) { if (v > n - 1) { //all vertices have been colored, success return true; } else { for (int i = 1; i <= m; i++) { //assign color i to vertex v q[v] = i; //System.out.println("color " + i + " to vertex " + (v + 1)); //check whether colors of v and its neighbors conflict boolean hasConflicted = hasConflicted(v); //System.out.println("hasConflicted = " + hasConflicted); if (hasConflicted == false) { //color the rest of G using m colors starting at vertex v+1, done by recursive call color(v+1, m) boolean success = color(v + 1, m); //if (the rest of G can be colored) // all vertices have been colored, success if (success) { return true; } } } //assign color 0 to vertex v and fail, this happens when none of the m colors can be assigned to vertex v q[v] = 0; return false; } } public boolean hasConflicted(int v) { for (int i = 0; i < n; i++) { if (i != v && matrix[i][v] == 1 && q[i] == q[v]) { return true; } } return false; } }
output formatting, using a for loop or while loop to incrementally print nodes in a heap
I have a nearly fully functional program but I am not able to format the output correctly. I am in desperate need of help as my project is past due already. I am a student working on a program that reads in a simple text file and creates a graph object of nodes from the input file. I am then, supposed to use a heap class to build the nodes into a Min-heap. Finally I am supposed to call a heap sort method to sort the nodes (preferably in descending order) I believe that my methods are correct and that my data is being correctly built into a min heap and is being correctly sorted. The only problem I am having is formatting the output which should be simple but for some reason isn't. The idea is this: my graph object contains 2 arrayLists the first is the unordered node list that was created from the input text file. The second is a blank arrayList that I am trying to copy nodes one at a time. I am trying to use a for loop or a while loop to first copy one single node into the empty ArrayList then call my build heap method to build a Min heap of only 1 element, then call my sort method to sort the heap of 1 element. Then, I want to copy in a second node and again build a min heap of 2 elements and then call my sort method on the 2 element heap. Then, copy in a third node and build the heap with 3 nodes, and then call the sort on the 3 element heap, and so on and so forth until all elements have been copied into the array list and the full heap is built and the sort method is called on all elements. My 3 element test file looks like this: ~ val X Y Z Xerxes 0 ~ ~ ~ York -1 ~ ~ ~ Zardoz 1 ~ ~ ~ My 6 element test file looks like this: ~ val A B C D E F Alfa 4 ~ ~ ~ ~ ~ ~ Bravo 6 ~ ~ ~ ~ ~ ~ Charlie -3 ~ ~ ~ ~ ~ ~ Delta -6 ~ ~ ~ ~ ~ ~ Echo 0 ~ ~ ~ ~ ~ ~ Foxtrot 55 ~ ~ ~ ~ ~ ~ the output should look something like this: Heaps: X YX YXZ HeapSort: YXZ XZY ZXY I am using several "test" files including one with 3 elements and one with 6 elements. My classes are as follows: import java.io.*; public class DelivB { File inputFile; File outputFile; PrintWriter output; Graph g; public DelivB( File in, Graph gr ) { inputFile = in; g = gr; // Get output file name. String inputFileName = inputFile.toString(); String baseFileName = inputFileName.substring( 0, inputFileName.length()-4 ); // Strip off ".txt" String outputFileName = baseFileName.concat( "_out.txt" ); outputFile = new File( outputFileName ); if ( outputFile.exists() ) { // For retests outputFile.delete(); } try { output = new PrintWriter(outputFile); writeGraphInfo(output); //System.out.println("=============================\n" + "testing testing testing Deliv B Class"); } catch (Exception x ) { System.err.format("Exception: %s%n", x); System.exit(0); } //System.out.println( "DelivB: To be implemented"); //System.out.println("\nDeliv B Class ++++++++++++++++++++++++++++++++++"); } public Graph getG() { return g; } public void setG(Graph g) { this.g = g; } /** Read the file containing the Strings, line by line, then process each line as it is read. **/ public void writeGraphInfo( PrintWriter output ) { try { // output the graph information. // I chose to output it to the console as well as the file for debugging purposes. System.out.println( "\n\n=========================================================================\n\n"); System.out.println( g ); output.println( g ); } catch (Exception x ) { System.err.format("ExceptionInner: %s%n", x); System.exit(0); } output.close(); } } // NEXT CLASS //=================================================== import java.util.*; // A node of a graph for the Spring 2018 ICS 340 program public class Node { String name; String val; // The value of the Node String abbrev; // The abbreviation for the Node ArrayList<Edge> outgoingEdges; ArrayList<Edge> incomingEdges; public Node( String theAbbrev ) { setAbbrev( theAbbrev ); val = null; name = null; outgoingEdges = new ArrayList<Edge>(); incomingEdges = new ArrayList<Edge>(); } public String getAbbrev() { return abbrev; } public String getName() { return name; } public String getVal() { return val; } public ArrayList<Edge> getOutgoingEdges() { return outgoingEdges; } public ArrayList<Edge> getIncomingEdges() { return incomingEdges; } public void setAbbrev( String theAbbrev ) { abbrev = theAbbrev; } public void setName( String theName ) { name = theName; } public void setVal( String theVal ) { val = theVal; } public void addOutgoingEdge( Edge e ) { outgoingEdges.add( e ); } public void addIncomingEdge( Edge e ) { incomingEdges.add( e ); } } //NEXT CLASS ================================================== //import java.util.*; // Edge between two nodes public class Edge { String label; Node tail; Node head; public Edge( Node tailNode, Node headNode, String theLabel ) { setLabel( theLabel ); setTail( tailNode ); setHead( headNode ); } public String getLabel() { return label; } public Node getTail() { return tail; } public Node getHead() { return head; } public void setLabel( String s ) { label = s; } public void setTail( Node n ) { tail = n; } public void setHead( Node n ) { head = n; } } //NEXT CLASS =================================================== import java.util.*; public class Heap { int heapSize; Graph gr; ArrayList<Node> unordered_nodelist; ArrayList<Node> ordered_nodelist; Node dummy = new Node("dummy node"); //constructor for heap object with the following attributes: //a graph object and an int representing the size of an arraylist of nodes public Heap(Graph g) { unordered_nodelist = g.getNodeList(); heapSize = unordered_nodelist.size(); ordered_nodelist = new ArrayList<Node>(); //for (int i = 0; i < heapSize; i++) //ordered_nodelist.add(dummy); //probably don't need this graph variable gr = g; } //getters and setters public ArrayList<Node> getUnordered_nodelist() { return unordered_nodelist; } public void setUnordered_nodelist(ArrayList<Node> unordered_nodelist) { this.unordered_nodelist = unordered_nodelist; } public ArrayList<Node> getOrdered_nodelist() { return ordered_nodelist; } public void setOrdered_nodelist(ArrayList<Node> ordered_nodelist) { this.ordered_nodelist = ordered_nodelist; } public int getHeapSize() { return heapSize; } public void setHeapSize(int heapSize) { this.heapSize = heapSize; } //heap methods public int Parent(ArrayList<Node> A, int i) { //if (i == 1) //return (Integer)null; if (i%2 != 0) return i/2; else return (i-1)/2; } public int Left(ArrayList<Node> A, int i) { //while (A.get(i).getVal() != null && A.get(i).getName() != null) //{ //if (2*i < heapSize) return (2*i)+1; //else //return (Integer)null; //} } public int Right(ArrayList<Node> A, int i) { //if ((2*i)+1 < heapSize) return 2*i+2; //else //return (Integer)null; } public void Heapify(ArrayList<Node> A, int i) { Node smallest; Node temp; int index; int l = Left(A,i); int r = Right(A,i); while (A.get(i).getVal() != null && A.get(i).getName() != null) { if (l <= heapSize-1 && Integer.parseInt(A.get(l).getVal()) < Integer.parseInt(A.get(i).getVal())) { //left child is smaller smallest = A.get(l); index = l; } else { //parent node is smaller smallest = A.get(i); index = i; } if (r <= heapSize-1 && Integer.parseInt(A.get(r).getVal()) < Integer.parseInt(smallest.getVal())) { //right child is smaller smallest = A.get(r); index = r; } if (index != i) { //if the smallest element is not the parent node //swap the smallest child with the parent temp = A.get(i); A.set(i, A.get(index)); A.set(index, temp); //recursively call heapify method to check next parent/child relationship Heapify(A, index); } } } //method to construct min heap from unordered arraylist of nodes public void Build_min_Heap(ArrayList<Node> A) { for (int k = 0; k<A.size()-1; k++) { //while (A.get(k).getVal() != null && A.get(k).getName() != null) //{ int i; int heapSize = A.size(); for (i = (heapSize/2); i>=0; i--) { Heapify(A, i); System.out.print(gr.toString2()+"\n"); } //} } } //decreases the value of a given node, used with insert method public void heap_Decrease_Key(ArrayList<Node> A, int i, int key) { Node parent; Node child; Node temp; if (key > i) { System.out.println("error key must be less than i"); //break; } A.get(i).setVal(Integer.toString(key)); while(i>0 && Integer.parseInt(A.get(Parent(A,i)).getVal()) > Integer.parseInt(A.get(i).getVal()) ) { parent = A.get(Parent(A,i)); child = A.get(i); temp = parent; //take the child node and place it in the parent node's place A.set(Parent(A,i), child); //take the parent node and place it in the child node's place A.set(i, temp); } } //method to sort in descending order, a min heap public void heap_Sort(ArrayList<Node> A) { Node temp; for (int k = 0; k<A.size()-1; k++) { //while (A.get(k).getVal() != null && A.get(k).getName() != null) //{ Build_min_Heap(A); System.out.println(gr.toString2()+"\n"); for(int i = A.size()-1; i >= 1; i--) { //exchange a[1] with a[i] temp = A.get(0); A.set(0, A.get(i)); A.set(i, temp); //decrement heapSize heapSize--; //recursive heapify call Heapify(A, 0); } //} } } public Node heap_Extract(ArrayList<Node> A) { Node min; min = A.get(0); A.set(0, A.get(heapSize-1)); //decrement heapSize heapSize--; Heapify(A, 0); return min; } public void heap_Insert(ArrayList<Node> A, int key) { heapSize++; A.get(heapSize-1).setVal(Integer.toString(2147483647)); heap_Decrease_Key(A, heapSize-1, key); } public String toString() { String s = "Graph g.\n"; //s += "Heaps: \n"; if ( ordered_nodelist.size() > 0 ) { //for loop to traverse an ArrayList of Nodes for(Node n : ordered_nodelist) { //output string to print each node's character abbreviation String t = n.getAbbrev(); s = s.concat(t); } } return s; } } //NEXT CLASS ================================================= import java.util.*; public class Heap { int heapSize; Graph gr; ArrayList<Node> unordered_nodelist; ArrayList<Node> ordered_nodelist; Node dummy = new Node("dummy node"); //constructor for heap object with the following attributes: //a graph object and an int representing the size of an arraylist of nodes public Heap(Graph g) { unordered_nodelist = g.getNodeList(); heapSize = unordered_nodelist.size(); ordered_nodelist = new ArrayList<Node>(); //for (int i = 0; i < heapSize; i++) //ordered_nodelist.add(dummy); //probably don't need this graph variable gr = g; } //getters and setters public ArrayList<Node> getUnordered_nodelist() { return unordered_nodelist; } public void setUnordered_nodelist(ArrayList<Node> unordered_nodelist) { this.unordered_nodelist = unordered_nodelist; } public ArrayList<Node> getOrdered_nodelist() { return ordered_nodelist; } public void setOrdered_nodelist(ArrayList<Node> ordered_nodelist) { this.ordered_nodelist = ordered_nodelist; } public int getHeapSize() { return heapSize; } public void setHeapSize(int heapSize) { this.heapSize = heapSize; } //heap methods public int Parent(ArrayList<Node> A, int i) { //if (i == 1) //return (Integer)null; if (i%2 != 0) return i/2; else return (i-1)/2; } public int Left(ArrayList<Node> A, int i) { //while (A.get(i).getVal() != null && A.get(i).getName() != null) //{ //if (2*i < heapSize) return (2*i)+1; //else //return (Integer)null; //} } public int Right(ArrayList<Node> A, int i) { //if ((2*i)+1 < heapSize) return 2*i+2; //else //return (Integer)null; } public void Heapify(ArrayList<Node> A, int i) { Node smallest; Node temp; int index; int l = Left(A,i); int r = Right(A,i); while (A.get(i).getVal() != null && A.get(i).getName() != null) { if (l <= heapSize-1 && Integer.parseInt(A.get(l).getVal()) < Integer.parseInt(A.get(i).getVal())) { //left child is smaller smallest = A.get(l); index = l; } else { //parent node is smaller smallest = A.get(i); index = i; } if (r <= heapSize-1 && Integer.parseInt(A.get(r).getVal()) < Integer.parseInt(smallest.getVal())) { //right child is smaller smallest = A.get(r); index = r; } if (index != i) { //if the smallest element is not the parent node //swap the smallest child with the parent temp = A.get(i); A.set(i, A.get(index)); A.set(index, temp); //recursively call heapify method to check next parent/child relationship Heapify(A, index); } } } //method to construct min heap from unordered arraylist of nodes public void Build_min_Heap(ArrayList<Node> A) { for (int k = 0; k<A.size()-1; k++) { //while (A.get(k).getVal() != null && A.get(k).getName() != null) //{ int i; int heapSize = A.size(); for (i = (heapSize/2); i>=0; i--) { Heapify(A, i); System.out.print(gr.toString2()+"\n"); } //} } } //decreases the value of a given node, used with insert method public void heap_Decrease_Key(ArrayList<Node> A, int i, int key) { Node parent; Node child; Node temp; if (key > i) { System.out.println("error key must be less than i"); //break; } A.get(i).setVal(Integer.toString(key)); while(i>0 && Integer.parseInt(A.get(Parent(A,i)).getVal()) > Integer.parseInt(A.get(i).getVal()) ) { parent = A.get(Parent(A,i)); child = A.get(i); temp = parent; //take the child node and place it in the parent node's place A.set(Parent(A,i), child); //take the parent node and place it in the child node's place A.set(i, temp); } } //method to sort in descending order, a min heap public void heap_Sort(ArrayList<Node> A) { Node temp; for (int k = 0; k<A.size()-1; k++) { //while (A.get(k).getVal() != null && A.get(k).getName() != null) //{ Build_min_Heap(A); System.out.println(gr.toString2()+"\n"); for(int i = A.size()-1; i >= 1; i--) { //exchange a[1] with a[i] temp = A.get(0); A.set(0, A.get(i)); A.set(i, temp); //decrement heapSize heapSize--; //recursive heapify call Heapify(A, 0); } //} } } public Node heap_Extract(ArrayList<Node> A) { Node min; min = A.get(0); A.set(0, A.get(heapSize-1)); //decrement heapSize heapSize--; Heapify(A, 0); return min; } public void heap_Insert(ArrayList<Node> A, int key) { heapSize++; A.get(heapSize-1).setVal(Integer.toString(2147483647)); heap_Decrease_Key(A, heapSize-1, key); } public String toString() { String s = "Graph g.\n"; //s += "Heaps: \n"; if ( ordered_nodelist.size() > 0 ) { //for loop to traverse an ArrayList of Nodes for(Node n : ordered_nodelist) { //output string to print each node's character abbreviation String t = n.getAbbrev(); s = s.concat(t); } } return s; } } //NEXT CLASS =============================================== import java.util.*; public class Graph { ArrayList<Node> nodeList; ArrayList<Edge> edgeList; public Graph() { nodeList = new ArrayList<Node>(); edgeList = new ArrayList<Edge>(); } public ArrayList<Node> getNodeList() { return nodeList; } public ArrayList<Edge> getEdgeList() { return edgeList; } public void addNode( Node n ) { nodeList.add( n ); } public void addEdge( Edge e ) { edgeList.add( e ); } //overridden toString() method to output both Nodes and the edges incumbent upon them public String toString() { String s = "Graph g.\n"; if ( nodeList.size() > 0 ) { //for loop to traverse an ArrayList of Nodes for( Node n : nodeList ) { //output string to print basic labels for each node String t = "\nNode " + n.getName() + ", abbrev " + n.getAbbrev() + ", value " + n.getVal() + "\n"; s = s.concat(t); //for loop to traverse an ArrayList of outgoing Edges incumbent upon //the given node in each iteration of the outer for loop for(Edge a : n.getOutgoingEdges()){ //output String to print data about each outgoing edge String q = n.getName() + " has edge to: " + a.getHead().getName() + " labeled: " + a.getLabel() + "\n"; s = s.concat(q); } //for loop to traverse an ArrayList of incomming Edges incumbent upon //the given node in each iteration of the outer for loop for(Edge a : n.getIncomingEdges()){ //output string to print data about each incomming edge String r = n.getName() + " has edge from: " + a.getTail().getName() + " labeled: " + a.getLabel() + "\n"; s = s.concat(r); } } s = s.concat("\n"); } return s; } public String toString2() { String s = "Graph g.\n"; if ( nodeList.size() > 0 ) { //for loop to traverse an ArrayList of Nodes for( Node n : nodeList ) { //output string to print each node's mnemonic String t = n.getAbbrev(); s = s.concat(t); } } return s; } } //NEXT CLASS ============================================== import javax.swing.*; import java.io.*; import java.util.*; import java.awt.*; import java.awt.event.*; /** ProgramA simply reads a file containing rows of space-separated Strings, ** your assignment is to print out those strings interpreted as a graph. ** ** #author ** Mike Stein **/ public class Prog340 extends JPanel implements ActionListener { private static final long serialVersionUID = 1L; // Keep Eclipse happy. File inputFile; File outputFile; PrintWriter output; JFileChooser fileChooser; Graph g; Heap h; String[] comboBoxList; // For putting names in Combo Box /** The main method instantiates a Prog340 class, which includes giving you a choice of things to do. ** The only one active now will be reading the graph file and having you parse it. ** ** #param args ** - Not used ** ** #throws FileNotFoundException ** - Thrown if the file selected is not found. Shouldn't happen with a FileChooser. **/ public static void main(String[] args) throws FileNotFoundException { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } }); } /** Create and show the GUI. ** For thread safety, this method should be invoked from the event-dispatching thread. **/ private static void createAndShowGUI() { // Create and set up the window JFrame frame = new JFrame("Prog340"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Create and set up the content pane. JComponent newContentPane = new Prog340(); newContentPane.setOpaque(true);; // content panes must be opaque frame.setContentPane(newContentPane);; // Display the window. frame.pack(); frame.setVisible(true); } /** The constructor creates a new ProgramA object, and sets up the input and output files. **/ public Prog340() { super( new BorderLayout() ); try { // I like the colorful FileChooser. UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); System.out.println( "Look and feel set."); } catch (Exception e) { // exit on exception. System.err.format("Exception: %s%n", e); System.exit(0); } fileChooser = new JFileChooser(); fileChooser.setDialogTitle("Choose a file"); // Start looking for files at the currect directory, not home. fileChooser.setCurrentDirectory(new File(".")); inputFile = null; g = new Graph(); // Select the action comboBoxList = new String[8]; comboBoxList[0] = new String("prog340: Select file and read graph"); comboBoxList[1] = new String("Deliv A: Write Graph Info"); comboBoxList[2] = new String ("Deliv B: Run Heap methods on selected file"); comboBoxList[3] = new String ("Deliv C: TBD"); comboBoxList[4] = new String ("Deliv D: TBD"); comboBoxList[5] = new String ("Deliv E: TBD"); comboBoxList[6] = new String ("Deliv F: TBD"); comboBoxList[7] = new String ("exit"); JComboBox actionList = new JComboBox( comboBoxList ); actionList.setName("Action List"); actionList.setSelectedIndex(0); actionList.addActionListener( this ); add( actionList, BorderLayout.PAGE_START ); } // Listen to the Combo Box public void actionPerformed( ActionEvent e ) { JComboBox cb = (JComboBox)e.getSource(); String actionName = (String)cb.getSelectedItem(); int actionIndex = cb.getSelectedIndex(); switch( actionIndex ) { case 0:{ g = new Graph(); readGraphInfo( g ); break; } case 1: DelivA dA = new DelivA( inputFile, g ); break; case 2: { int numElements = 1; int j =0; int k; //rewritten switch statement case to make DelivB combo box work g = new Graph(); readGraphInfo( g ); DelivB dB = new DelivB(inputFile, g); h = new Heap(g); System.out.println("unordered list: \n"); System.out.println(g.toString()); System.out.println("=========================================="); //h.Build_min_Heap(h.getOrdered_nodelist()); for (j = 0; j <= h.getHeapSize(); j++) //while (j <= h.getHeapSize()) //for (Node n : h.getOrdered_nodelist()) { //copy node elements from unordered arraylist to new empty arraylist h.getOrdered_nodelist().add(h.getUnordered_nodelist().get(j)); System.out.println("unordered node list size is: " + h.getUnordered_nodelist().size()+ "\n"); System.out.println("ordered node list size is: " + h.getOrdered_nodelist().size()); System.out.println("\nvalue of j is: " + j + "\n"); System.out.println("Heaps: \n"); h.Build_min_Heap(h.getOrdered_nodelist()); System.out.println("after build heap call: \n" ); System.out.println(h.toString()); //System.out.println("\ngraph class toString method: \n"); //System.out.println(g.toString() + "\n"); //System.out.println(g.toString2()); System.out.println("HeapSort: \n"); h.heap_Sort(h.getOrdered_nodelist()); System.out.println("after heapsort call: \n"); System.out.println(h.toString()); j++; //System.out.println("\n graph class toString method: \n"); //System.out.println(g.toString() + "\n"); //System.out.println(g.toString2()); //System.out.println("the"+j+"th element in the original array is: \n"+h.getOrdered_nodelist().get(j).getAbbrev()); //System.out.println("the"+j+"th element in the new array is: \n"+h.getUnordered_nodelist().get(j).getAbbrev()); //System.out.println("\n after build heap method call, the output is as follows: " + g.toString()); } break; } case 3: DelivC dC = new DelivC( inputFile, g ); break; case 4: DelivD dD = new DelivD( inputFile, g ); break; case 5: DelivE dE = new DelivE( inputFile, g ); break; case 6: DelivF dF = new DelivF( inputFile, g ); break; case 7: System.out.println( "Goodbye"); System.exit(0); default: System.out.println( "Invalid choice" ); System.exit(0); } } /** Read the file containing the Strings, line by line, then process each line as it is read. **/ public void readGraphInfo( Graph g ) { try { if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { // Instantiate the selected input and output files. inputFile = fileChooser.getSelectedFile(); System.out.println( "Chosen file = " + inputFile + "\n"); } // read text file Scanner sc = new Scanner( inputFile ); // First line special: It contains "~", and "val", and the nodes with the edges. String firstLine = sc.nextLine(); String[] splitString = firstLine.split( " +" ); // Ignore first two fields of first line, Every other field is a node. for ( int i = 2; i < splitString.length; i++ ) { Node n = new Node( splitString[i] ); g.addNode( n ); } // Every other line gives the name and value of the Node, and any edges. int nodeIndex = 0; ArrayList<Node> nodeList = g.getNodeList(); while ( sc.hasNextLine() ) { String nextLine = sc.nextLine(); splitString = nextLine.split(" +"); Node n = nodeList.get( nodeIndex ); n.setName( splitString[0] ); n.setVal( splitString[1] ); for ( int i = 2; i < splitString.length; i++ ) { if ( !splitString[i].equals("~") ) { Node head = nodeList.get(i-2); Edge e = new Edge( n, head, splitString[i] ); g.addEdge( e ); n.addOutgoingEdge( e ); head.addIncomingEdge( e ); } } nodeIndex++; } sc.close(); } catch (Exception x) { System.err.format("ExceptionOuter: %s%n", x); } } }
Java maze won't print
I have to make a maze for a java assignment, and I was able to finish most of it. I was provided with an outline of the code that had all the methods. Can someone help me? My issue is that the maze wont print out, and I can't figure out why. package maze; public class Maze { private char direction; private int r; // x position of the mouse private int c; //y position of the mouse private boolean exitFound = false; public Maze(int[][] arrMaze) { this.r = arrMaze.length - 1; this.c = 0; } //Prints out the maze without solution public void displayMaze(int[][] arrMaze) { //display the maze putting blank spaces where there are 1's in the array and putting //another symbol where there are 0's to show the maze without the solution for(int i=0; i<arrMaze.length; i++){ System.out.println(" "); for(int j=0; j<arrMaze[i].length; j++){ if(arrMaze[i][j] == 0){ System.out.print("#"); } if(arrMaze[i][j] == 1) { System.out.print(" "); } if(arrMaze[i][j] == 2){ System.out.print("#"); } if(arrMaze[i][j] == 3){ System.out.println("~"); } } } } //displays the Maze with the path taken public void displayPath(int[][] arrMaze) { //show the user how far the mouse has gone since the start. //The path the mouse has gone will be filled in but the path ahead will not. for (int i = 0; i < arrMaze.length; i++) { System.out.println(" "); for (int j = 0; j < arrMaze[i].length; j++) { if (arrMaze[i][j] == 3) { System.out.print("#"); } else if (arrMaze[i][j] == 2) { System.out.print("~"); } else if (arrMaze[i][j] == 0) { System.out.print("#"); } else { } } } } public boolean takeStep(int[][] newMaze) { // moveNorth(newMaze) for (int i = 0; i < newMaze.length; i++) { System.out.println(" "); for (int j = 0; j < newMaze[i].length; j++) { if (newMaze[r][c] == 3) { moveNorth(newMaze); System.out.print("~"); } else if (newMaze[r][c] == 2) { System.out.print("#"); } else { } } } return isAnExit(newMaze); } public void moveNorth(int[][] arrMaze) { //complete the code here /*method will check for a 0 or a 1 in the position above the current position * and then if not a 0 will change the current position to the row above it, but in the same column. */ if (arrMaze[r][c - 1] != 0) { arrMaze[r][c - 1] = 3; arrMaze[r][c + 1] = 2; } else { moveSouth(arrMaze); } displayPath(arrMaze); } public void moveSouth(int[][] arrMaze) { //method will check for a 0 or a 1 in the position below the current position and then if not a 0 //it will change the current position to the row below it, but in the same column. if (arrMaze[r][c + 1] != 0) { arrMaze[r][c + 1] = 3; arrMaze[r][c + 1] = 2; } else { moveNorth(arrMaze); } displayPath(arrMaze); } public void moveEast(int[][] arrMaze) { //method will check for a 0 or a 1 in the position to the right of  the current position and then if //not a 0 will change the current position to the column to the right but the same row. if (arrMaze[r + 1][c] != 0) { arrMaze[r + 1][c] = 3; arrMaze[r - 1][c] = 2; } else { moveWest(arrMaze); } displayPath(arrMaze); } public void moveWest(int[][] arrMaze) { //method will check for a 0 or a 1 in the position to the left of  the current position and then if //not a 0 will change the current position to the column to the left but the same row. if (arrMaze[r - 1][c] != 0) { arrMaze[r - 1][c] = 3; arrMaze[r + 1][c] = 2; } else { } displayPath(arrMaze); } private boolean isAnExit(int[][] arrMaze) { //method will return true if the user arrives into the last column of the array because there is only one //location in the last column that is a 1, so if the user reaches the array[i].length then that means that it found an exit. if (arrMaze[r][c] > arrMaze.length) { exitFound = true; } else { exitFound = false; } return exitFound; } //finds the path without stopping at every step //method will show the complete path from start to finish of the maze and the suggested route to the end. public void findExit(int[][] arrMaze) { if (arrMaze[r][c] > arrMaze.length) { for (int i = 0; i < arrMaze.length; i++) { takeStep(arrMaze); } } } } This is the test code. I was provided the test code, and I haven't changed it. package maze; import java.util.Scanner; public class TestMaze { public static void main(String[] args) { int[][] mazeArray = { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0}, {0,0,0,1,1,1,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1}, {0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0}, {0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0}, {1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; Maze myMaze = new Maze(mazeArray); boolean keepAsking = true; Scanner scan = new Scanner(System.in); String input = ""; myMaze.displayPath(mazeArray); System.out.println("Maze"); do { System.out.println("T = Take a step | S = Show path | Q = Quit"); System.out.print("Enter command: "); input = scan.nextLine(); input.trim(); input.toLowerCase(); if(input.equals("t")) { keepAsking = !myMaze.takeStep(mazeArray); System.out.println("Which direction would you like to go? N, S, E, W?"); String direction = scan.nextLine(); if(direction.equalsIgnoreCase("n")) myMaze.moveNorth(mazeArray); if(direction.equalsIgnoreCase("s")) myMaze.moveSouth(mazeArray); if(direction.equalsIgnoreCase("e")) myMaze.moveEast(mazeArray); if(direction.equalsIgnoreCase("w")) myMaze.moveWest(mazeArray); } else if(input.equals("s")) { myMaze.findExit(mazeArray); keepAsking = false; } else if(input.equals("q")) { keepAsking = false; } else { System.out.println("ERR: Invalid input"); } } while(keepAsking); System.out.println("Quitting program..."); scan.close(); } }
You need to call displayMaze() (in displayPath()) to print it. Currently, you're not calling the method, meaning that your code will never print the maze as it's no being instructed to. Also, where are you assigning values to r and c? I think you meant to use i and j in your displayPath() method ([i][j] instead of [r][c]).
I imagine you're throwing an error somewhere because your r and c values are undefined everywhere they are used. Try adding code to initialize and update these values, then you should see your maze print.
Dijkstra adjacency list
I have run into a problem converting pseudocode of Dijkstras algorithm into actual code. I was given and adjacency list such as "Location - adjacent location - distance to location," example for one node: AAA AAC 180 AAD 242 AAH 40. My task was to read a file organized as adjacency list as described, and compute the shortest path from one node to another. Here is the Dijkstra pseudocode: void dijkstra( Vertex s ) { for each Vertex v { v.dist = INFINITY; v.known = false; } s.dist = 0; while( there is an unknown distance vertex ) { Vertex v = smallest unknown distance vertex; v.known = true; for each Vertex w adjacent to v if( !w.known ) { DistType cvw = cost of edge from v to w; if( v.dist + cvw < w.dist ) { // Update w decrease( w.dist to v.dist + cvw ); w.path = v; } } } } im having the most trouble with the line "for each Vertex w adjacent to v" Here is my nonworking code: import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; public class Dijkstra { public static boolean isInteger(String s) { return isInteger(s, 10); } public static boolean isInteger(String s, int radix) { if (s.isEmpty()) return false; for (int i = 0; i < s.length(); i++) { if (i == 0 && s.charAt(i) == '-') { if (s.length() == 1) return false; else continue; } if (Character.digit(s.charAt(i), radix) < 0) return false; } return true; } public static void dijkstra(Vertex[] a, Vertex s, int lineCount) { int i = 0; while (i < (lineCount)) // each Vertex v { a[i].dist = Integer.MAX_VALUE; a[i].known = false; i++; } s.dist = 0; int min = Integer.MAX_VALUE; // while (!(a[0].known == true && a[1].known == true && a[2].known == true && a[3].known == true && a[4].known == true && a[5].known == true && a[6].known == true && a[7].known == true && a[8].known == true && a[9].known == true && a[10].known == true && a[11].known == true && a[12].known == true)) { System.out.println("here"); for (int b = 0; b < lineCount; b++) { if (a[b].dist < min && a[b].known == false) { min = a[b].dist; } } int c = 0; while (c < lineCount) { if (a[c].dist == min && a[c].known == false) { break; } c++; } System.out.println(min); a[c].known = true; int adjSize = a[c].adj.size(); int current = 0; System.out.println(adjSize); while (current < adjSize - 1) { String currentAdjacent = (String) a[c].adj.get(current); int p = 0; while (p < lineCount) { if (a[p].name.equals(currentAdjacent)) { if (!a[p].known) { String cvwString = (String) a[c].distance.get(current); int cvw = Integer.parseInt(cvwString); System.out.println(" This is cvw" + cvw); System.out.println("Here2"); if (a[c].dist + cvw < a[p].dist) { a[p].dist = a[c].dist + cvw; a[p].path = a[c]; } } } p++; } current++; } } } public static class Vertex { public List adj; // Adjacency list public List distance; public boolean known; public int dist; // DistType is probably int public Vertex path; public String name; // Other fields and methods as needed } public static void printPath(Vertex v) { if (v.path != null) { printPath(v.path); System.out.print(" to "); } System.out.print(v); } public static void main(String[] args) throws IOException { int lineCounter = 0; BufferedReader br = new BufferedReader(new FileReader("airport.txt")); try { StringBuilder sb = new StringBuilder(); String line = br.readLine(); while (line != null) { sb.append(line); sb.append(System.lineSeparator()); line = br.readLine(); lineCounter = lineCounter + 1; } Vertex[] arr = new Vertex[lineCounter]; for (int i = 0; i < lineCounter; i++) { arr[i] = new Vertex(); arr[i].adj = new LinkedList<String>(); arr[i].distance = new LinkedList<Integer>(); } ; // int arrayCounter = 0; String everything = sb.toString(); String[] lines = everything.split("\\s*\\r?\\n\\s*"); for (String line1 : lines) { arr[arrayCounter] = new Vertex(); arr[arrayCounter].adj = new LinkedList<String>(); arr[arrayCounter].distance = new LinkedList<Integer>(); String[] result = line1.split("\\s+"); for (int x = 0; x < result.length; x++) { if (x == 0) { arr[arrayCounter].name = result[0]; continue; } else if (isInteger(result[x])) { arr[arrayCounter].distance.add(result[x]); continue; } else { arr[arrayCounter].adj.add(result[x]); continue; } } arrayCounter++; } for (int i = 0; i < 12; i++) { System.out.println(arr[i].name); } System.out.println(lineCounter); dijkstra(arr, arr[3], lineCounter - 1); printPath(arr[11]); } finally { br.close(); } } } Using my vertex class as is I was using a series of while loops to first, traverse the adjacency strings stored in a linked list while comparing to see which vertex is equivalent to the adjacency list string. Is there a better way to code "for each Vertex w adjacent to v" using my Vertex class? And apologies ahead for messy code and any others style sins i may have committed. Thanks!
To solve this problem you need a bunch of "Node" objects, stored in a HashMap, keyed on Source Location. In the node, you need a collection of references to adjacent "Node" objects (or at least their "key" so you can write logic against it. The "Node" also needs to know it's location and distance to each "adjacent" node. Think Lundon Underground Tube Maps - each station connects to at least one other station. Usually two or more. Therefore, adjacent nodes to tube stations are the immediate next stops you can get to from that station. Once you have that data structure in place, you can then use a recursive routine to iterate through each individual node. It should then iterate through each child node (aka adjacent node), and track distances from the initial (source) node to the current node by storing this data in a HashMap and using the current accumulated distance whilst recursing (or "walking" the graph"). This tracking information should be part of your method signature when recursing. You will also need to track the current path you have taken when recursing, in order to avoid circular loops (which will ultimately and ironically cause a StackOverflowError). You can do this by using a HashSet. This Set should track the source and current node's location as the entry key. If you see this present during your recursion, then you have already seen it, so don't continue processing. I'm not going to code the solution for you because I suspect that you ask more specific questions as you work your way through understanding the answer, which are very likely answered elsewhere.
store a binary search tree graph into an array using recursion and print it out
I already build a binary search tree. The primitive data type I store in the tree is integer. I try to store it on a 2-D char array and then print it out as the graph shown below(the numbers represent row numbers and column numbers and I do not need to print it, ignoring "-" symbol please, I only use it to indicate the exact position) -----0---1---2---3---4---5---6---7---8---9---10---11---12---13---14---15---16 0---------------------------------------12 1--------------------------------/-------------------\ 2----------------------8--------------------------------------14 3-----------------/----------\ -----------------------------------------\ 4-------------5----------------9-------------------------------------------34 5--------/-------------------------------------------------------------/-------------\ 6---2---------------------------------------------------------24------------------------35 number 12 need to store on location [0][8], the middle of the first row. number 4 store on[2][4], number 14=[2][12], 5=[4][2], 9=[4][9] and so on. row number 1 which is second row, "/" is on position[1][6] and "\" is on position[1][10] etc.they are also on the middle between two numbers following is my code public class MainClass { public static void main(String[] args) { //level represents row number; // start indicates the column I am going to //store number in, and end is a fixed column number // BinarySearchTree is a BinaryTree type instance, // I already story integers on it and follow with the format // of binary search trees, and I did tested it. int level=0; int start=0; int end=80; BinaryTree.plot(BinarySearchTree, level, start, end); } private static class BinaryTree { private BinaryNode root; static char[][] offset = new char [10][20]; public BinaryTree(){ root = null; } public BinaryTree(Object x){ root = new BinaryNode(x); } public boolean isEmpty(){ return root == null; } public Object getRootobj() throws BinaryTreeException{ if(root == null) throw new BinaryTreeException("Empty Tree"); else return root.element; } public BinaryTree getLeft() throws BinaryTreeException{ if(root == null) throw new BinaryTreeException("Empty Tree"); else { BinaryTree t = new BinaryTree(); t.root = root.left; return t; } } public BinaryTree getRight() throws BinaryTreeException{ if(root == null) throw new BinaryTreeException("Empty Tree"); else { BinaryTree t = new BinaryTree(); t.root = root.right; return t; } } public static void plot(BinaryTree t, int level, int start, int end){ if(!t.isEmpty()){ plot(t.getLeft(), level+2, start/2, end/2); String string = Integer.toString((Integer)t.getRootobj()); for(char c: string.toCharArray()) offset[level][start++]=c; if(!(t.getLeft().isEmpty())) offset[++level][start/4*3] = '/'; if(!(t.getRight().isEmpty())) offset[++level][((start+end)/2+start)/2] = '\\'; plot(t.getRight(), level+2, end/2, end); } for(int i = 0; i<10; i++){ for(int j= 0; j<20; j++) System.out.print(offset[i][j]); } } } private static class BinaryNode { Object element; BinaryNode left,right; BinaryNode() { this(0); } BinaryNode(Object e) { this(e, null, null); } BinaryNode(Object e, BinaryNode ln, BinaryNode m){ element=e; left=ln; right=m; } } } Question: the method plot I used to store and print out binarysearchtree did not work, which causes a java.lang.ArrayIndexOutOfBoundsException: can anyone take a look at it. appreciated for the help.
Your fixed-size char-Array cannot cope with your dynamic sized BinaryTree. For your given example alone you need way more then 20 characters per line! That's where your Exception is coming from. But to give you an idea of an alternative approach - even though it took a while, made the following additions to your code: First, I added a method to the BinaryNode class: int getDepth() { int subTreeDepth; if (left == null && right == null) { subTreeDepth = 0; } else if (left == null) { subTreeDepth = right.getDepth(); } else if (right == null) { subTreeDepth = left.getDepth(); } else { subTreeDepth = Math.max(left.getDepth(), right.getDepth()); } return 1 + subTreeDepth; } Second, I removed your fixed char-Array and replaced the whole plotting algorithm in your BinaryTree (I just couldn't wrap my head around all those relative array-index manipulations): public void plot() { if (root == null) { throw new BinaryTreeException("Empty Tree"); } int lineCount = 2 * root.getDepth() - 1; StringBuilder[] lines = new StringBuilder[lineCount]; for (int lineIndex = 0; lineIndex < lineCount; lineIndex++) { lines[lineIndex] = new StringBuilder(); } // get the right most node (which contains the largest element value) BinaryNode rightMostNode = root; while (rightMostNode.right != null) { rightMostNode = rightMostNode.right; } // check how many characters we have to reserve for a single node element int maxElementLength = String.valueOf(rightMostNode.element).length(); plot(root, 0, 0, maxElementLength, lines); for (StringBuilder singleLine : lines) { System.out.println(singleLine.toString()); } } private void plot(BinaryNode subTreeRoot, int offset, int lineIndex, int elementLength, StringBuilder[] lines) { int actualOffset; if (subTreeRoot.left == null) { actualOffset = offset; } else { actualOffset = offset + (int) Math.pow(2, subTreeRoot.left.getDepth() - 1) * elementLength; } StringBuilder currentLine = lines[lineIndex]; String elementValue = String.valueOf(subTreeRoot.element); for (int lineFillIndex = currentLine.length() + elementValue.length() / 2; lineFillIndex < actualOffset; lineFillIndex++) { currentLine.append(' '); } currentLine.append(elementValue); if (subTreeRoot.left != null) { // draw connection to left sub tree int connectPosition = (actualOffset - offset) * 3 / 4 + offset; StringBuilder connectLine = lines[lineIndex + 1]; for (int lineFillIndex = connectLine.length(); lineFillIndex < connectPosition; lineFillIndex++) { connectLine.append(' '); } connectLine.append('/'); // insert the left part of the next value line plot(subTreeRoot.left, offset, lineIndex + 2, elementLength, lines); } if (subTreeRoot.right != null) { // draw connection to right sub tree int connectPosition = actualOffset + elementLength - elementValue.length() / 2; if (subTreeRoot.right.left != null) { connectPosition += (int) Math.pow(2, subTreeRoot.right.left.getDepth() - 1) * elementLength / 2; } StringBuilder connectLine = lines[lineIndex + 1]; for (int lineFillIndex = connectLine.length(); lineFillIndex < connectPosition; lineFillIndex++) { connectLine.append(' '); } connectLine.append('\\'); // insert the right part of the next value line plot(subTreeRoot.right, actualOffset + elementLength, lineIndex + 2, elementLength, lines); } } For a tree similar to the one, you included in your question: BinaryTree binarySearchTree = new BinaryTree( new BinaryNode(12, new BinaryNode(8, new BinaryNode(5, new BinaryNode(3), null), new BinaryNode(9)), new BinaryNode(14, null, new BinaryNode(34, new BinaryNode(24), new BinaryNode(35))))); binarySearchTree.plot(); I get the following output: 12 / \ 8 14 / \ \ 5 9 34 / / \ 3 24 35