Someone recently asked me how to do this, so I figured I’d write it up in Java since it’s still the language I’m most comfortable with:
Node.java
package com.evanhoffman.bst;
import org.apache.log4j.Logger;
/**
* Node in a binary search tree in which values = are in the right branch.
* @author evan
*
* @param
*/
public class Node<v extends Comparable> {
private static Logger logger = Logger.getLogger(Node.class);
private Node left = null;
private Node right = null;
private V value = null;
public Node(V t) {
this.value = t;
}
public V getValue() {
return value;
}
public boolean isLeaf() {
return (left == null && right == null);
}
public void addNode(Node node) {
if (node.getValue().compareTo(value) < 0) {
if (left == null) {
left = node;
logger.debug("Assigning "+node.getValue()+" "+
"to left child of node "+value);
} else {
left.addNode(node);
}
} else {
if (right == null) {
right = node;
logger.debug("Assigning "+node.getValue()+" "+
"to right child of node "+value);
} else {
right.addNode(node);
}
}
}
public V findMaxStrictlyLessThan(V t) {
return findMaxStrictlyLessThan(t, null);
}
/**
* Returns the greatest value in the tree strictly
* less than (as defined by {@link Comparable#compareTo(Object)} the given value.
* @param t
* @return
*/
private V findMaxStrictlyLessThan(V t, V currentMax) {
if (t.compareTo(value) = current node "+value+", checking right (if exists)");
currentMax = value;
return right == null ? currentMax : right.findMaxStrictlyLessThan(t, currentMax);
}
}
@Override
public String toString() {
if (isLeaf()) {
return "{value="+value+"}";
} else {
return "{value="+value+", left="+left+", right="+right+"}";
}
}
}
IntBstBuilder.java:
package com.evanhoffman.bst;
import java.util.Random;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
public class IntBstBuilder {
private static int min = 0;
private static int max = 200;
private static int size = 10;
private static Random rng = new Random();
private static Logger logger = Logger.getLogger(IntBstBuilder.class);
public static void main(String args[]) {
BasicConfigurator.configure();
Node root = new Node((max - min)/2);
for (int i = 0; i < size; i++) {
int num = (Math.abs(rng.nextInt()) % (max - min)) + min;
Node newNode = new Node(num);
root.addNode(newNode);
}
logger.info(root);
logger.info(root.findMaxStrictlyLessThan(50));
logger.info(root.findMaxStrictlyLessThan(90));
logger.info(root.findMaxStrictlyLessThan(130));
logger.info(root.findMaxStrictlyLessThan(220));
logger.info(root.findMaxStrictlyLessThan(-100));
}
}
Output:
0 [main] DEBUG com.evanhoffman.bst.Node - Assigning 192 to right child of node 100
1 [main] DEBUG com.evanhoffman.bst.Node - Assigning 140 to left child of node 192
1 [main] DEBUG com.evanhoffman.bst.Node - Assigning 162 to right child of node 140
1 [main] DEBUG com.evanhoffman.bst.Node - Assigning 54 to left child of node 100
1 [main] DEBUG com.evanhoffman.bst.Node - Assigning 155 to left child of node 162
1 [main] DEBUG com.evanhoffman.bst.Node - Assigning 118 to left child of node 140
2 [main] DEBUG com.evanhoffman.bst.Node - Assigning 52 to left child of node 54
2 [main] DEBUG com.evanhoffman.bst.Node - Assigning 184 to right child of node 162
2 [main] DEBUG com.evanhoffman.bst.Node - Assigning 41 to left child of node 52
2 [main] DEBUG com.evanhoffman.bst.Node - Assigning 161 to right child of node 155
2 [main] INFO com.evanhoffman.bst.IntBstBuilder - {value=100, left={value=54, left={value=52, left={value=41}, right=null}, right=null}, right={value=192, left={value=140, left={value=118}, right={value=162, left={value=155, left=null, right={value=161}}, right={value=184}}}, right=null}}
2 [main] DEBUG com.evanhoffman.bst.Node - 50 is less than current node 100, checking left (if it exists)
2 [main] DEBUG com.evanhoffman.bst.Node - 50 is less than current node 54, checking left (if it exists)
2 [main] DEBUG com.evanhoffman.bst.Node - 50 is less than current node 52, checking left (if it exists)
2 [main] DEBUG com.evanhoffman.bst.Node - 50 is >= current node 41, checking right (if exists)
2 [main] INFO com.evanhoffman.bst.IntBstBuilder - 41
2 [main] DEBUG com.evanhoffman.bst.Node - 90 is less than current node 100, checking left (if it exists)
2 [main] DEBUG com.evanhoffman.bst.Node - 90 is >= current node 54, checking right (if exists)
2 [main] INFO com.evanhoffman.bst.IntBstBuilder - 54
2 [main] DEBUG com.evanhoffman.bst.Node - 130 is >= current node 100, checking right (if exists)
2 [main] DEBUG com.evanhoffman.bst.Node - 130 is less than current node 192, checking left (if it exists)
3 [main] DEBUG com.evanhoffman.bst.Node - 130 is less than current node 140, checking left (if it exists)
3 [main] DEBUG com.evanhoffman.bst.Node - 130 is >= current node 118, checking right (if exists)
3 [main] INFO com.evanhoffman.bst.IntBstBuilder - 118
3 [main] DEBUG com.evanhoffman.bst.Node - 220 is >= current node 100, checking right (if exists)
3 [main] DEBUG com.evanhoffman.bst.Node - 220 is >= current node 192, checking right (if exists)
3 [main] INFO com.evanhoffman.bst.IntBstBuilder - 192
3 [main] DEBUG com.evanhoffman.bst.Node - -100 is less than current node 100, checking left (if it exists)
3 [main] DEBUG com.evanhoffman.bst.Node - -100 is less than current node 54, checking left (if it exists)
3 [main] DEBUG com.evanhoffman.bst.Node - -100 is less than current node 52, checking left (if it exists)
3 [main] DEBUG com.evanhoffman.bst.Node - -100 is less than current node 41, checking left (if it exists)
3 [main] INFO com.evanhoffman.bst.IntBstBuilder -
StringBstBuilder.java:
package com.evanhoffman.bst;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
public class StringBstBuilder {
private static int size = 100;
private static Random rng = new Random();
private static Logger logger = Logger.getLogger(StringBstBuilder.class);
private ArrayList words = new ArrayList();
public ArrayList getWords() {
return words;
}
StringBstBuilder(File f, int maxLines) {
logger.debug("Creating "+this.getClass()+" with word list file: "+f+" up to "+maxLines+" lines");
int i = 0;
try {
BufferedReader br = new BufferedReader(new FileReader(f));
String line = null;
while ((i < maxLines) && (line = br.readLine()) != null) {
words.add(line);
i++;
}
logger.debug("Added "+words.size()+" words to list");
} catch (FileNotFoundException fe) {
logger.error("File not found: "+f,fe);
throw new RuntimeException(fe);
} catch (IOException ie) {
logger.error("IO Exception: "+ie.getMessage(),ie);
throw new RuntimeException(ie);
}
}
public static void main(String args[]) {
BasicConfigurator.configure();
StringBstBuilder sbt = new StringBstBuilder(new File(args[0]), Integer.parseInt(args[1]));
ArrayList words = sbt.getWords();
int wordListSize = words.size();
// Random number between 1/4 and 3/4 through the list.
int seedWordIndex = (Math.abs(rng.nextInt()) % (wordListSize/2)) + (wordListSize / 4);
Node root = new Node(words.get(seedWordIndex));
logger.debug("Root word: "+root.getValue());
for (int i = 0; i < size; i++) {
int index = (Math.abs(rng.nextInt()) % (words.size()));
Node newNode = new Node(words.get(index));
root.addNode(newNode);
}
logger.info("Entire tree: "+root);
String[] searches = {"andy", "joker", "kale", "moonshine", "zebra"};
for (String str : searches) {
logger.info("Search for "+str+": ");
String s = root.findMaxStrictlyLessThan(str);
logger.info("max word: "+s);
}
}
}
Output:
0 [main] DEBUG com.evanhoffman.bst.StringBstBuilder - Creating class com.evanhoffman.bst.StringBstBuilder with word list file: /Users/evan/Downloads/scowl-7.1/final/english-words.20 up to 10000 lines
47 [main] DEBUG com.evanhoffman.bst.StringBstBuilder - Added 7951 words to list
48 [main] DEBUG com.evanhoffman.bst.StringBstBuilder - Root word: patient's
48 [main] DEBUG com.evanhoffman.bst.Node - Assigning scroll's to right child of node patient's
48 [main] DEBUG com.evanhoffman.bst.Node - Assigning dual to left child of node patient's
48 [main] DEBUG com.evanhoffman.bst.Node - Assigning bat to left child of node dual
48 [main] DEBUG com.evanhoffman.bst.Node - Assigning moderate to right child of node dual
48 [main] DEBUG com.evanhoffman.bst.Node - Assigning abort to left child of node bat
48 [main] DEBUG com.evanhoffman.bst.Node - Assigning migrates to left child of node moderate
48 [main] DEBUG com.evanhoffman.bst.Node - Assigning terrifying to right child of node scroll's
48 [main] DEBUG com.evanhoffman.bst.Node - Assigning equilibrium to left child of node migrates
48 [main] DEBUG com.evanhoffman.bst.Node - Assigning polynomial to left child of node scroll's
48 [main] DEBUG com.evanhoffman.bst.Node - Assigning tomatoes to right child of node terrifying
48 [main] DEBUG com.evanhoffman.bst.Node - Assigning unusable to right child of node tomatoes
48 [main] DEBUG com.evanhoffman.bst.Node - Assigning nailing to right child of node moderate
48 [main] DEBUG com.evanhoffman.bst.Node - Assigning supporter to left child of node terrifying
49 [main] DEBUG com.evanhoffman.bst.Node - Assigning prosecution to right child of node polynomial
49 [main] DEBUG com.evanhoffman.bst.Node - Assigning management to right child of node equilibrium
49 [main] DEBUG com.evanhoffman.bst.Node - Assigning disabled to right child of node bat
49 [main] DEBUG com.evanhoffman.bst.Node - Assigning planted to left child of node polynomial
49 [main] DEBUG com.evanhoffman.bst.Node - Assigning midday to right child of node management
49 [main] DEBUG com.evanhoffman.bst.Node - Assigning cloth to left child of node disabled
49 [main] DEBUG com.evanhoffman.bst.Node - Assigning hip to left child of node management
49 [main] DEBUG com.evanhoffman.bst.Node - Assigning tune's to left child of node unusable
49 [main] DEBUG com.evanhoffman.bst.Node - Assigning mortal to left child of node nailing
49 [main] DEBUG com.evanhoffman.bst.Node - Assigning dangers to right child of node cloth
49 [main] DEBUG com.evanhoffman.bst.Node - Assigning concentrate to left child of node dangers
49 [main] DEBUG com.evanhoffman.bst.Node - Assigning intimate to right child of node hip
49 [main] DEBUG com.evanhoffman.bst.Node - Assigning stairs to left child of node supporter
49 [main] DEBUG com.evanhoffman.bst.Node - Assigning attorney to right child of node abort
49 [main] DEBUG com.evanhoffman.bst.Node - Assigning globally to left child of node hip
49 [main] DEBUG com.evanhoffman.bst.Node - Assigning vertical to right child of node unusable
49 [main] DEBUG com.evanhoffman.bst.Node - Assigning close's to left child of node cloth
49 [main] DEBUG com.evanhoffman.bst.Node - Assigning debatable to right child of node dangers
50 [main] DEBUG com.evanhoffman.bst.Node - Assigning guarding to right child of node globally
50 [main] DEBUG com.evanhoffman.bst.Node - Assigning aided to left child of node attorney
50 [main] DEBUG com.evanhoffman.bst.Node - Assigning contend to right child of node concentrate
50 [main] DEBUG com.evanhoffman.bst.Node - Assigning shined to left child of node stairs
50 [main] DEBUG com.evanhoffman.bst.Node - Assigning journals to right child of node intimate
50 [main] DEBUG com.evanhoffman.bst.Node - Assigning warmed to right child of node vertical
50 [main] DEBUG com.evanhoffman.bst.Node - Assigning blaming to left child of node close's
50 [main] DEBUG com.evanhoffman.bst.Node - Assigning ingredient to left child of node intimate
50 [main] DEBUG com.evanhoffman.bst.Node - Assigning gleaning to left child of node globally
50 [main] DEBUG com.evanhoffman.bst.Node - Assigning boys to right child of node blaming
50 [main] DEBUG com.evanhoffman.bst.Node - Assigning stream's to right child of node stairs
50 [main] DEBUG com.evanhoffman.bst.Node - Assigning tragedy to left child of node tune's
50 [main] DEBUG com.evanhoffman.bst.Node - Assigning brands to right child of node boys
50 [main] DEBUG com.evanhoffman.bst.Node - Assigning revenge to right child of node prosecution
50 [main] DEBUG com.evanhoffman.bst.Node - Assigning knight to right child of node journals
50 [main] DEBUG com.evanhoffman.bst.Node - Assigning discard to right child of node disabled
50 [main] DEBUG com.evanhoffman.bst.Node - Assigning successor to right child of node stream's
51 [main] DEBUG com.evanhoffman.bst.Node - Assigning synonymous to right child of node supporter
51 [main] DEBUG com.evanhoffman.bst.Node - Assigning bow to left child of node boys
51 [main] DEBUG com.evanhoffman.bst.Node - Assigning satisfaction to right child of node revenge
51 [main] DEBUG com.evanhoffman.bst.Node - Assigning mutters to right child of node mortal
51 [main] DEBUG com.evanhoffman.bst.Node - Assigning tray to right child of node tragedy
51 [main] DEBUG com.evanhoffman.bst.Node - Assigning linkage to right child of node knight
51 [main] DEBUG com.evanhoffman.bst.Node - Assigning face's to left child of node gleaning
51 [main] DEBUG com.evanhoffman.bst.Node - Assigning decreasing to right child of node debatable
51 [main] DEBUG com.evanhoffman.bst.Node - Assigning spoiling to right child of node shined
51 [main] DEBUG com.evanhoffman.bst.Node - Assigning slave's to left child of node spoiling
51 [main] DEBUG com.evanhoffman.bst.Node - Assigning clarified to right child of node brands
51 [main] DEBUG com.evanhoffman.bst.Node - Assigning inspection to right child of node ingredient
51 [main] DEBUG com.evanhoffman.bst.Node - Assigning technically to right child of node synonymous
51 [main] DEBUG com.evanhoffman.bst.Node - Assigning supervises to right child of node successor
51 [main] DEBUG com.evanhoffman.bst.Node - Assigning disconnect to right child of node discard
51 [main] DEBUG com.evanhoffman.bst.Node - Assigning whence to right child of node warmed
51 [main] DEBUG com.evanhoffman.bst.Node - Assigning creator to right child of node contend
52 [main] DEBUG com.evanhoffman.bst.Node - Assigning oppress to right child of node nailing
52 [main] DEBUG com.evanhoffman.bst.Node - Assigning magnificent to right child of node linkage
52 [main] DEBUG com.evanhoffman.bst.Node - Assigning launch to left child of node linkage
52 [main] DEBUG com.evanhoffman.bst.Node - Assigning compensation to left child of node concentrate
52 [main] DEBUG com.evanhoffman.bst.Node - Assigning cave to left child of node clarified
52 [main] DEBUG com.evanhoffman.bst.Node - Assigning unbearable to right child of node tune's
52 [main] DEBUG com.evanhoffman.bst.Node - Assigning verifies to left child of node vertical
52 [main] DEBUG com.evanhoffman.bst.Node - Assigning compact to left child of node compensation
52 [main] DEBUG com.evanhoffman.bst.Node - Assigning immense to left child of node ingredient
52 [main] DEBUG com.evanhoffman.bst.Node - Assigning empire to left child of node equilibrium
52 [main] DEBUG com.evanhoffman.bst.Node - Assigning foreseeable to right child of node face's
52 [main] DEBUG com.evanhoffman.bst.Node - Assigning joking to left child of node journals
52 [main] DEBUG com.evanhoffman.bst.Node - Assigning opts to right child of node oppress
52 [main] DEBUG com.evanhoffman.bst.Node - Assigning convicting to left child of node creator
52 [main] DEBUG com.evanhoffman.bst.Node - Assigning divisions to right child of node disconnect
52 [main] DEBUG com.evanhoffman.bst.Node - Assigning fascinate to left child of node foreseeable
52 [main] DEBUG com.evanhoffman.bst.Node - Assigning reactions to left child of node revenge
52 [main] DEBUG com.evanhoffman.bst.Node - Assigning discriminated to left child of node divisions
53 [main] DEBUG com.evanhoffman.bst.Node - Assigning unrealistic to right child of node unbearable
53 [main] DEBUG com.evanhoffman.bst.Node - Assigning crowds to right child of node creator
53 [main] DEBUG com.evanhoffman.bst.Node - Assigning marketed to left child of node midday
53 [main] DEBUG com.evanhoffman.bst.Node - Assigning broad to left child of node cave
53 [main] DEBUG com.evanhoffman.bst.Node - Assigning socket to right child of node slave's
53 [main] DEBUG com.evanhoffman.bst.Node - Assigning verbal to left child of node verifies
53 [main] DEBUG com.evanhoffman.bst.Node - Assigning register's to right child of node reactions
53 [main] DEBUG com.evanhoffman.bst.Node - Assigning attributes to right child of node attorney
53 [main] DEBUG com.evanhoffman.bst.Node - Assigning clarity to right child of node clarified
53 [main] DEBUG com.evanhoffman.bst.Node - Assigning engage to right child of node empire
53 [main] DEBUG com.evanhoffman.bst.Node - Assigning succeeded to left child of node successor
53 [main] DEBUG com.evanhoffman.bst.Node - Assigning resembled to right child of node register's
53 [main] DEBUG com.evanhoffman.bst.Node - Assigning kernel to left child of node knight
53 [main] DEBUG com.evanhoffman.bst.Node - Assigning dot to right child of node divisions
53 [main] DEBUG com.evanhoffman.bst.Node - Assigning wrecked to right child of node whence
54 [main] DEBUG com.evanhoffman.bst.Node - Assigning gratuitously to left child of node guarding
54 [main] DEBUG com.evanhoffman.bst.Node - Assigning syndicate to left child of node synonymous
54 [main] INFO com.evanhoffman.bst.StringBstBuilder - Entire tree: {value=patient's, left={value=dual, left={value=bat, left={value=abort, left=null, right={value=attorney, left={value=aided}, right={value=attributes}}}, right={value=disabled, left={value=cloth, left={value=close's, left={value=blaming, left=null, right={value=boys, left={value=bow}, right={value=brands, left=null, right={value=clarified, left={value=cave, left={value=broad}, right=null}, right={value=clarity}}}}}, right=null}, right={value=dangers, left={value=concentrate, left={value=compensation, left={value=compact}, right=null}, right={value=contend, left=null, right={value=creator, left={value=convicting}, right={value=crowds}}}}, right={value=debatable, left=null, right={value=decreasing}}}}, right={value=discard, left=null, right={value=disconnect, left=null, right={value=divisions, left={value=discriminated}, right={value=dot}}}}}}, right={value=moderate, left={value=migrates, left={value=equilibrium, left={value=empire, left=null, right={value=engage}}, right={value=management, left={value=hip, left={value=globally, left={value=gleaning, left={value=face's, left=null, right={value=foreseeable, left={value=fascinate}, right=null}}, right=null}, right={value=guarding, left={value=gratuitously}, right=null}}, right={value=intimate, left={value=ingredient, left={value=immense}, right={value=inspection}}, right={value=journals, left={value=joking}, right={value=knight, left={value=kernel}, right={value=linkage, left={value=launch}, right={value=magnificent}}}}}}, right={value=midday, left={value=marketed}, right=null}}}, right=null}, right={value=nailing, left={value=mortal, left=null, right={value=mutters}}, right={value=oppress, left=null, right={value=opts}}}}}, right={value=scroll's, left={value=polynomial, left={value=planted}, right={value=prosecution, left=null, right={value=revenge, left={value=reactions, left=null, right={value=register's, left=null, right={value=resembled}}}, right={value=satisfaction}}}}, right={value=terrifying, left={value=supporter, left={value=stairs, left={value=shined, left=null, right={value=spoiling, left={value=slave's, left=null, right={value=socket}}, right=null}}, right={value=stream's, left=null, right={value=successor, left={value=succeeded}, right={value=supervises}}}}, right={value=synonymous, left={value=syndicate}, right={value=technically}}}, right={value=tomatoes, left=null, right={value=unusable, left={value=tune's, left={value=tragedy, left=null, right={value=tray}}, right={value=unbearable, left=null, right={value=unrealistic}}}, right={value=vertical, left={value=verifies, left={value=verbal}, right=null}, right={value=warmed, left=null, right={value=whence, left=null, right={value=wrecked}}}}}}}}}
55 [main] INFO com.evanhoffman.bst.StringBstBuilder - Search for andy:
55 [main] DEBUG com.evanhoffman.bst.Node - andy is less than current node patient's, checking left (if it exists)
55 [main] DEBUG com.evanhoffman.bst.Node - andy is less than current node dual, checking left (if it exists)
55 [main] DEBUG com.evanhoffman.bst.Node - andy is less than current node bat, checking left (if it exists)
55 [main] DEBUG com.evanhoffman.bst.Node - andy is >= current node abort, checking right (if exists)
55 [main] DEBUG com.evanhoffman.bst.Node - andy is less than current node attorney, checking left (if it exists)
55 [main] DEBUG com.evanhoffman.bst.Node - andy is >= current node aided, checking right (if exists)
55 [main] INFO com.evanhoffman.bst.StringBstBuilder - max word: aided
56 [main] INFO com.evanhoffman.bst.StringBstBuilder - Search for joker:
56 [main] DEBUG com.evanhoffman.bst.Node - joker is less than current node patient's, checking left (if it exists)
56 [main] DEBUG com.evanhoffman.bst.Node - joker is >= current node dual, checking right (if exists)
56 [main] DEBUG com.evanhoffman.bst.Node - joker is less than current node moderate, checking left (if it exists)
56 [main] DEBUG com.evanhoffman.bst.Node - joker is less than current node migrates, checking left (if it exists)
56 [main] DEBUG com.evanhoffman.bst.Node - joker is >= current node equilibrium, checking right (if exists)
56 [main] DEBUG com.evanhoffman.bst.Node - joker is less than current node management, checking left (if it exists)
56 [main] DEBUG com.evanhoffman.bst.Node - joker is >= current node hip, checking right (if exists)
56 [main] DEBUG com.evanhoffman.bst.Node - joker is >= current node intimate, checking right (if exists)
56 [main] DEBUG com.evanhoffman.bst.Node - joker is less than current node journals, checking left (if it exists)
56 [main] DEBUG com.evanhoffman.bst.Node - joker is less than current node joking, checking left (if it exists)
56 [main] INFO com.evanhoffman.bst.StringBstBuilder - max word: intimate
56 [main] INFO com.evanhoffman.bst.StringBstBuilder - Search for kale:
56 [main] DEBUG com.evanhoffman.bst.Node - kale is less than current node patient's, checking left (if it exists)
56 [main] DEBUG com.evanhoffman.bst.Node - kale is >= current node dual, checking right (if exists)
56 [main] DEBUG com.evanhoffman.bst.Node - kale is less than current node moderate, checking left (if it exists)
56 [main] DEBUG com.evanhoffman.bst.Node - kale is less than current node migrates, checking left (if it exists)
56 [main] DEBUG com.evanhoffman.bst.Node - kale is >= current node equilibrium, checking right (if exists)
57 [main] DEBUG com.evanhoffman.bst.Node - kale is less than current node management, checking left (if it exists)
57 [main] DEBUG com.evanhoffman.bst.Node - kale is >= current node hip, checking right (if exists)
57 [main] DEBUG com.evanhoffman.bst.Node - kale is >= current node intimate, checking right (if exists)
57 [main] DEBUG com.evanhoffman.bst.Node - kale is >= current node journals, checking right (if exists)
57 [main] DEBUG com.evanhoffman.bst.Node - kale is less than current node knight, checking left (if it exists)
57 [main] DEBUG com.evanhoffman.bst.Node - kale is less than current node kernel, checking left (if it exists)
57 [main] INFO com.evanhoffman.bst.StringBstBuilder - max word: journals
57 [main] INFO com.evanhoffman.bst.StringBstBuilder - Search for moonshine:
57 [main] DEBUG com.evanhoffman.bst.Node - moonshine is less than current node patient's, checking left (if it exists)
57 [main] DEBUG com.evanhoffman.bst.Node - moonshine is >= current node dual, checking right (if exists)
57 [main] DEBUG com.evanhoffman.bst.Node - moonshine is >= current node moderate, checking right (if exists)
57 [main] DEBUG com.evanhoffman.bst.Node - moonshine is less than current node nailing, checking left (if it exists)
57 [main] DEBUG com.evanhoffman.bst.Node - moonshine is less than current node mortal, checking left (if it exists)
57 [main] INFO com.evanhoffman.bst.StringBstBuilder - max word: moderate
57 [main] INFO com.evanhoffman.bst.StringBstBuilder - Search for zebra:
57 [main] DEBUG com.evanhoffman.bst.Node - zebra is >= current node patient's, checking right (if exists)
57 [main] DEBUG com.evanhoffman.bst.Node - zebra is >= current node scroll's, checking right (if exists)
57 [main] DEBUG com.evanhoffman.bst.Node - zebra is >= current node terrifying, checking right (if exists)
58 [main] DEBUG com.evanhoffman.bst.Node - zebra is >= current node tomatoes, checking right (if exists)
58 [main] DEBUG com.evanhoffman.bst.Node - zebra is >= current node unusable, checking right (if exists)
58 [main] DEBUG com.evanhoffman.bst.Node - zebra is >= current node vertical, checking right (if exists)
58 [main] DEBUG com.evanhoffman.bst.Node - zebra is >= current node warmed, checking right (if exists)
58 [main] DEBUG com.evanhoffman.bst.Node - zebra is >= current node whence, checking right (if exists)
58 [main] DEBUG com.evanhoffman.bst.Node - zebra is >= current node wrecked, checking right (if exists)
58 [main] INFO com.evanhoffman.bst.StringBstBuilder - max word: wrecked