Vous êtes sur la page 1sur 19

Code From the Video

Binary Tree in Java BinaryTree.java

001
002
003
004

public class BinaryTree {


Node root;

005

public void addNode(int key, String name) {

006
007
008

// Create a new Node and initialize it

009

Node newNode = new Node(key, name);

010
011
012

// If there is no root this becomes root

013

if (root == null) {

014
015
016

root = newNode;

017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040

} else {
// Set root as the Node we will start
// with as we traverse the tree
Node focusNode = root;
// Future parent for our new Node
Node parent;
while (true) {
// root is the top parent so we start
// there
parent = focusNode;
// Check if the new node should go on
// the left side of the parent node
if (key < focusNode.key) {
// Switch focus to the left child

041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081

focusNode = focusNode.leftChild;
// If the left child has no children
if (focusNode == null) {
// then place the new node on the left of it
parent.leftChild = newNode;
return; // All Done
}
} else { // If we get here put the node on the right
focusNode = focusNode.rightChild;
// If the right child has no children
if (focusNode == null) {
// then place the new node on the right of it
parent.rightChild = newNode;
return; // All Done
}
}
}
}
}
// All nodes are visited in ascending order
// Recursion is used to go to one node and
// then go to its child nodes and so forth
public void inOrderTraverseTree(Node focusNode) {

082
083
084
085

if (focusNode != null) {
// Traverse the left node

086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101

inOrderTraverseTree(focusNode.leftChild);
// Visit the currently focused on node
System.out.println(focusNode);
// Traverse the right node
inOrderTraverseTree(focusNode.rightChild);
}
}
public void preorderTraverseTree(Node focusNode) {

102
103
104
105
106
107
108
109
110
111
112
113
114

if (focusNode != null) {
System.out.println(focusNode);
preorderTraverseTree(focusNode.leftChild);
preorderTraverseTree(focusNode.rightChild);
}
}
public void postOrderTraverseTree(Node focusNode) {

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

if (focusNode != null) {
postOrderTraverseTree(focusNode.leftChild);
postOrderTraverseTree(focusNode.rightChild);
System.out.println(focusNode);
}
}
public Node findNode(int key) {
// Start at the top of the tree

131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

Node focusNode = root;


// While we haven't found the Node
// keep looking
while (focusNode.key != key) {
// If we should search to the left
if (key < focusNode.key) {
// Shift the focus Node to the left child
focusNode = focusNode.leftChild;
} else {
// Shift the focus Node to the right child
focusNode = focusNode.rightChild;
}
// The node wasn't found

156

if (focusNode == null)

157

return null;

158
159
160

161

return focusNode;

162
163
164

165

public static void main(String[] args) {

166
167
168
169
170
171
172
173
174

BinaryTree theTree = new BinaryTree();


theTree.addNode(50, "Boss");
theTree.addNode(25, "Vice President");
theTree.addNode(15, "Office Manager");

175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198

theTree.addNode(30, "Secretary");
theTree.addNode(75, "Sales Manager");
theTree.addNode(85, "Salesman 1");
// Different ways to traverse binary trees
// theTree.inOrderTraverseTree(theTree.root);
// theTree.preorderTraverseTree(theTree.root);
// theTree.postOrderTraverseTree(theTree.root);
// Find the node with key 75
System.out.println("\nNode with the key 75");
System.out.println(theTree.findNode(75));
}
}
class Node {

199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

int key;
String name;
Node leftChild;
Node rightChild;
Node(int key, String name) {
this.key = key;
this.name = name;
}
public String toString() {

214
215
216
217

return name + " has the key " + key;

/*
* return name + " has the key " + key + "\nLeft Child: " +
218
leftChild +

219
220
221
222
223
224

* "\nRight Child: " + rightChild + "\n";


*/
}
}

How to print binary tree diagram?


up vote95down vote
97

favorite

How can I print a binary tree in Java so that the output is like:
4
/\
2 5

My node:
public class Node<A extends Comparable> {
Node<A> left, right;
A data;
public Node(A data){
this.data = data;
}
}

I've created simple binary tree printer. You can use and modify it as you want, but it's
not optimized anyway. I think that a lot of things can be improved here ;)
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class BTreePrinterTest {
private static Node<Integer> test1() {
Node<Integer> root = new Node<Integer>(2);
Node<Integer> n11 = new Node<Integer>(7);
Node<Integer> n12 = new Node<Integer>(5);
Node<Integer> n21 = new Node<Integer>(2);
Node<Integer> n22 = new Node<Integer>(6);

Node<Integer>
Node<Integer>
Node<Integer>
Node<Integer>
Node<Integer>
Node<Integer>
Node<Integer>
Node<Integer>
Node<Integer>
Node<Integer>

n23
n24
n31
n32
n33
n34
n35
n36
n37
n38

=
=
=
=
=
=
=
=
=
=

new
new
new
new
new
new
new
new
new
new

Node<Integer>(3);
Node<Integer>(6);
Node<Integer>(5);
Node<Integer>(8);
Node<Integer>(4);
Node<Integer>(5);
Node<Integer>(8);
Node<Integer>(4);
Node<Integer>(5);
Node<Integer>(8);

root.left = n11;
root.right = n12;
n11.left = n21;
n11.right = n22;
n12.left = n23;
n12.right = n24;
n21.left = n31;
n21.right = n32;
n22.left = n33;
n22.right = n34;
n23.left = n35;
n23.right = n36;
n24.left = n37;
n24.right = n38;
}

return root;

private static Node<Integer> test2() {


Node<Integer> root = new Node<Integer>(2);
Node<Integer> n11 = new Node<Integer>(7);
Node<Integer> n12 = new Node<Integer>(5);
Node<Integer> n21 = new Node<Integer>(2);
Node<Integer> n22 = new Node<Integer>(6);
Node<Integer> n23 = new Node<Integer>(9);
Node<Integer> n31 = new Node<Integer>(5);
Node<Integer> n32 = new Node<Integer>(8);
Node<Integer> n33 = new Node<Integer>(4);
root.left = n11;
root.right = n12;
n11.left = n21;
n11.right = n22;
n12.right = n23;
n22.left = n31;
n22.right = n32;
n23.left = n33;
return root;

}
public static void main(String[] args) {
BTreePrinter.printNode(test1());
BTreePrinter.printNode(test2());
}
}
class Node<T extends Comparable<?>> {
Node<T> left, right;
T data;

public Node(T data) {


this.data = data;
}

class BTreePrinter {
public static <T extends Comparable<?>> void printNode(Node<T> root) {
int maxLevel = BTreePrinter.maxLevel(root);
}

printNodeInternal(Collections.singletonList(root), 1, maxLevel);

private static <T extends Comparable<?>> void printNodeInternal(List<Node<T>>


nodes, int level, int maxLevel) {
if (nodes.isEmpty() || BTreePrinter.isAllElementsNull(nodes))
return;
int
int
int
int

floor = maxLevel - level;


endgeLines = (int) Math.pow(2, (Math.max(floor - 1, 0)));
firstSpaces = (int) Math.pow(2, (floor)) - 1;
betweenSpaces = (int) Math.pow(2, (floor + 1)) - 1;

BTreePrinter.printWhitespaces(firstSpaces);
List<Node<T>> newNodes = new ArrayList<Node<T>>();
for (Node<T> node : nodes) {
if (node != null) {
System.out.print(node.data);
newNodes.add(node.left);
newNodes.add(node.right);
} else {
newNodes.add(null);
newNodes.add(null);
System.out.print(" ");
}
BTreePrinter.printWhitespaces(betweenSpaces);
}
System.out.println("");

for (int i = 1; i <= endgeLines; i++) {


for (int j = 0; j < nodes.size(); j++) {
BTreePrinter.printWhitespaces(firstSpaces - i);
if (nodes.get(j) == null) {
BTreePrinter.printWhitespaces(endgeLines + endgeLines + i + 1);
continue;
}
if (nodes.get(j).left != null)
System.out.print("/");
else
BTreePrinter.printWhitespaces(1);
BTreePrinter.printWhitespaces(i + i - 1);
if (nodes.get(j).right != null)
System.out.print("\\");
else
BTreePrinter.printWhitespaces(1);
}

BTreePrinter.printWhitespaces(endgeLines + endgeLines - i);

System.out.println("");
}
}

printNodeInternal(newNodes, level + 1, maxLevel);

private static void printWhitespaces(int count) {


for (int i = 0; i < count; i++)
System.out.print(" ");
}
private static <T extends Comparable<?>> int maxLevel(Node<T> node) {
if (node == null)
return 0;
return Math.max(BTreePrinter.maxLevel(node.left),
BTreePrinter.maxLevel(node.right)) + 1;
}
private static <T> boolean isAllElementsNull(List<T> list) {
for (Object object : list) {
if (object != null)
return false;
}
}

return true;

Output 1 :
2

/\
/ \
/
\
/
\
7
5
/\
/\
/ \ / \
2 6 3 6
/\/\/\/\
58458458

Output 2 :
2
/\
/ \
/
\
/
\
7
5
/\
\
/ \
\
2 6
9
/\
/
58
4

Print a [large] tree by lines.


output example:
z
c
a
b
d
e
asdf
f

code:
public class TreeNode {
final String name;
final List<TreeNode> children;
public TreeNode(String name, List<TreeNode> children) {
this.name = name;

this.children = children;

public void print() {


print("", true);
}
private void print(String prefix, boolean isTail) {
System.out.println(prefix + (isTail ? " " : " ") + name);
for (int i = 0; i < children.size() - 1; i++) {
children.get(i).print(prefix + (isTail ? " " : " "), false);
}
if (children.size() > 0) {
children.get(children.size() - 1).print(prefix + (isTail ?" " : " "), true);
}
}
}

P.S. Sorry, this answer doesn't exactly focus on "binary" trees. It just gets googled
when requesting somewhat for printing a tree. Solution is inspired by the "tree"
command in linux.

public static class Node<T extends Comparable<T>> {


T value;
Node<T> left, right;
public void insertToTree(T v) {
if (value == null) {
value = v;
return;
}
if (v.compareTo(value) < 0) {
if (left == null) {
left = new Node<T>();
}
left.insertToTree(v);
} else {
if (right == null) {
right = new Node<T>();
}
right.insertToTree(v);
}
}
public void printTree(OutputStreamWriter out) throws IOException {
if (right != null) {
right.printTree(out, true, "");
}
printNodeValue(out);
if (left != null) {
left.printTree(out, false, "");
}

}
private void printNodeValue(OutputStreamWriter out) throws IOException {
if (value == null) {
out.write("<null>");
} else {
out.write(value.toString());
}
out.write('\n');
}
// use string and not stringbuffer on purpose as we need to change the indent at
each recursion
private void printTree(OutputStreamWriter out, boolean isRight, String indent) throws
IOException {
if (right != null) {
right.printTree(out, true, indent + (isRight ? "
":"|
"));
}
out.write(indent);
if (isRight) {
out.write(" /");
} else {
out.write(" \\");
}
out.write("----- ");
printNodeValue(out);
if (left != null) {
left.printTree(out, false, indent + (isRight ? " |
":"
"));
}
}
}

will print:
/----- 20
|
\----- 15
/----- 14
|
\----- 13
/----- 12
|
|
/----- 11
|
\----- 10
|
\----- 9
8
|
/----- 7
|
/----- 6
|
|
\----- 5
\----- 4
|
/----- 3
\----- 2
\----- 1

for the input


8 4 12 2 6 10 14 1 3 5 7 9 11 13 20 15

this is a variant from @anurag's answer - it was bugging me to see the extra |s

I've made an improved algorithm for this, which handles nicely nodes with different size. It
prints top-down using lines.
package alg;
import java.util.ArrayList;
import java.util.List;
/**
* Binary tree printer
*
* @author MightyPork
*/
public class TreePrinter
{
/** Node that can be printed */
public interface PrintableNode
{
/** Get left child */
PrintableNode getLeft();
/** Get right child */
PrintableNode getRight();

/** Get text to be printed */


String getText();

/**
* Print a tree
*
* @param root
*
tree root node
*/
public static void print(PrintableNode root)
{
List<List<String>> lines = new ArrayList<List<String>>();
List<PrintableNode> level = new ArrayList<PrintableNode>();
List<PrintableNode> next = new ArrayList<PrintableNode>();
level.add(root);
int nn = 1;
int widest = 0;
while (nn != 0) {

List<String> line = new ArrayList<String>();


nn = 0;
for (PrintableNode n : level) {
if (n == null) {
line.add(null);
next.add(null);
next.add(null);
} else {
String aa = n.getText();
line.add(aa);
if (aa.length() > widest) widest = aa.length();
next.add(n.getLeft());
next.add(n.getRight());

if (n.getLeft() != null) nn++;


if (n.getRight() != null) nn++;

}
if (widest % 2 == 1) widest++;
lines.add(line);
List<PrintableNode> tmp = level;
level = next;
next = tmp;
next.clear();
}
int perpiece = lines.get(lines.size() - 1).size() * (widest + 4);
for (int i = 0; i < lines.size(); i++) {
List<String> line = lines.get(i);
int hpw = (int) Math.floor(perpiece / 2f) - 1;
if (i > 0) {
for (int j = 0; j < line.size(); j++) {

= '';

// split node
char c = ' ';
if (j % 2 == 1) {
if (line.get(j - 1) != null) {
c = (line.get(j) != null) ? '' : '';
} else {
if (j < line.size() && line.get(j) != null) c
}
}
System.out.print(c);
// lines and spaces
if (line.get(j) == null) {
for (int k = 0; k < perpiece - 1; k++) {
System.out.print(" ");

}
} else {
for (int k = 0; k < hpw; k++)
System.out.print(j % 2 ==
}
System.out.print(j % 2 == 0 ?
for (int k = 0; k < hpw; k++)
System.out.print(j % 2 ==
}

{
0 ? " " : "");
"" : "");
{
0 ? "" : " ");

}
}
System.out.println();
}

// print line of numbers


for (int j = 0; j < line.size(); j++) {
String f = line.get(j);
if (f == null) f = "";
int gap1 = (int) Math.ceil(perpiece / 2f - f.length() /
2f);

int gap2 = (int) Math.floor(perpiece / 2f - f.length() /

2f);
// a number
for (int k = 0; k < gap1; k++) {
System.out.print(" ");
}
System.out.print(f);
for (int k = 0; k < gap2; k++) {
System.out.print(" ");
}
}
System.out.println();
perpiece /= 2;
}

To use this for your Tree, let your Node class implement PrintableNode.
Example output:
2952:0

1249:-1
5866:0

491:-1
1572:0
4786:1
6190:0

339:0
5717:0
6061:0
6271:0

private StringBuilder prettyPrint(Node root, int currentHeight, int


totalHeight) {
StringBuilder sb = new StringBuilder();
int spaces = getSpaceCount(totalHeight-currentHeight + 1);
if(root == null) {
//create a 'spatial' block and return it
String row = String.format("%"+(2*spaces+1)+"s%n", "");
//now repeat this row space+1 times
String block = new String(new char[spaces+1]).replace("\0",
row);
return new StringBuilder(block);
}
if(currentHeight==totalHeight) return new
StringBuilder(root.data+"");
int slashes = getSlashCount(totalHeight-currentHeight +1);
sb.append(String.format("%"+(spaces+1)+"s%"+spaces+"s",
root.data+"", ""));
sb.append("\n");
//now print / and \
// but make sure that left and right exists
char leftSlash = root.left == null? ' ':'/';
char rightSlash = root.right==null? ' ':'\\';
int spaceInBetween = 1;
for(int i=0, space = spaces-1; i<slashes; i++, space --,
spaceInBetween+=2) {
for(int j=0; j<space; j++) sb.append(" ");
sb.append(leftSlash);
for(int j=0; j<spaceInBetween; j++) sb.append(" ");
sb.append(rightSlash+"");
for(int j=0; j<space; j++) sb.append(" ");
sb.append("\n");
}
//sb.append("\n");
//now get string representations of left and right subtrees
StringBuilder leftTree = prettyPrint(root.left, currentHeight+1,
totalHeight);
StringBuilder rightTree = prettyPrint(root.right,
currentHeight+1, totalHeight);
// now line by line print the trees side by side
Scanner leftScanner = new Scanner(leftTree.toString());
Scanner rightScanner = new Scanner(rightTree.toString());
//
spaceInBetween+=1;
while(leftScanner.hasNextLine()) {
if(currentHeight==totalHeight-1) {
sb.append(String.format("%-2s %2s",
leftScanner.nextLine(), rightScanner.nextLine()));
sb.append("\n");
spaceInBetween-=2;
}
else {
sb.append(leftScanner.nextLine());
sb.append(" ");
sb.append(rightScanner.nextLine()+"\n");
}

}
return sb;
}
private int getSpaceCount(int height) {
return (int) (3*Math.pow(2, height-2)-1);
}
private int getSlashCount(int height) {
if(height <= 3) return height -1;
return (int) (3*Math.pow(2, height-3)-1);
}

https://github.com/murtraja/java-binary-tree-printer
only works for 1 to 2 digit integers (i was lazy to make it generic)

Vous aimerez peut-être aussi