我有以下二进制搜索树,我正在尝试使用此wiki中所示的方法删除节点
http://en.wikipedia.org/wiki/Binary_search_tree#Deletion
主要思想是在两个子树都存在时修改lrMerge(以下代码中的方法)。然后,要删除的节点被左树中最右边的节点(其自身被删除)替换。下面的代码末尾有一个测试文件。我试图改变IrMerge就像维基删除代码 - 但是没有成功。
class KeyNotFoundInTableException extends Exception {
}
public class BinaryTreeLUT {
/**
* The member class Key is used for the indexing keys of the LUT. It
* is a String with basic comparative methods added.
*/
protected class Key {
public Key(String s) {
kString = s;
}
public boolean equals(Key k) {
return kString.equals(k.toString());
}
public boolean lessThan(Key k) {
return (kString.compareTo(k.toString()) < 0);
}
public boolean greaterThan(Key k) {
return (kString.compareTo(k.toString()) > 0);
}
public String toString() {
return kString;
}
private String kString;
}
/**
* The member class Entry encapsulates an entry of the LUT and contains
* a {key, value} pair.
*/
protected class Entry {
public Entry(Key k, Object v) {
key = k;
value = v;
}
protected Key key;
protected Object value;
}
/**
* The member class BSTreeNode encapsulates node of the binary search
* tree, which contains a LUT entry and links to left and right
* subtrees.
*/
protected class BSTreeNode {
public BSTreeNode(Entry e) {
kvPair = e;
left = null;
right = null;
}
public BSTreeNode(Entry e, BSTreeNode l, BSTreeNode r) {
kvPair = e;
left = l;
right = r;
}
protected Entry kvPair;
protected BSTreeNode left;
protected BSTreeNode right;
}
//Single protected data member - the LUT is stored in a sequence.
protected BSTreeNode root;
/**
* Default constructor - no need to specify capacity of LUT.
*/
public BinaryTreeLUT() {
root = null;
}
/**
* Inserts a new key-value pair into the look-up table.
*/
public void insert(String key, Object value) {
BSTreeNode newNode = new BSTreeNode(new Entry(new Key(key), value));
addToTree(newNode, root);
}
/**
* Removes the key-value pair with the specified key from the look-up
* table.
*/
public void remove(String key) throws KeyNotFoundInTableException {
Key searchKey = new Key(key);
removeFromTree(searchKey, root);
}
/**
* Retrieves the key-value pair with the specified key from the look-up
* table.
*/
public Object retrieve(String key) throws KeyNotFoundInTableException {
Key searchKey = new Key(key);
BSTreeNode treeNode = getFromTree(searchKey, root);
return treeNode.kvPair.value;
}
/**
* Updates the key-value pair with the specified key with the new
* specified value.
*/
public void update(String key, Object value) throws KeyNotFoundInTableException {
Key searchKey = new Key(key);
BSTreeNode treeNode = getFromTree(searchKey, root);
treeNode.kvPair.value = value;
}
/**
* Returns a string listing all the key-entry pairs in the LUT
*/
public String toString() {
return treeString(root);
}
//protected methods implementing recursive operations on the tree.
/**
* Adds newNode to the tree rooted at curNode recursively.
*/
protected void addToTree(BSTreeNode newNode, BSTreeNode curNode) {
//Special case for empty tree.
if(curNode == null) {
root = newNode;
}
//General case: recurse left or right depending on comparison.
else if(curNode.kvPair.key.lessThan(newNode.kvPair.key)) {
if(curNode.left == null) {
curNode.left = newNode;
}
else {
addToTree(newNode, curNode.left);
}
}
else {
if(curNode.right == null) {
curNode.right = newNode;
}
else {
addToTree(newNode, curNode.right);
}
}
}
/**
* Returns the node containing k from the tree rooted at node.
*/
protected BSTreeNode getFromTree(Key k, BSTreeNode node) throws KeyNotFoundInTableException {
if(node == null) {
throw new KeyNotFoundInTableException();
}
else if(node.kvPair.key.equals(k)) {
return node;
}
else if(node.kvPair.key.lessThan(k)) {
return getFromTree(k, node.left);
}
else {
return getFromTree(k, node.right);
}
}
/**
* Removes the node containing k from the tree rooted at node.
*/
protected void removeFromTree(Key k, BSTreeNode node) throws KeyNotFoundInTableException {
//Special case for empty tree.
if(node == null) {
throw new KeyNotFoundInTableException();
}
//Special case when deleting the root node.
else if(root.kvPair.key.equals(k)) {
root = lrMerge(root);
}
//If the key at the current node is less than
//the search key, go to the left subtree.
else if(node.kvPair.key.lessThan(k)) {
//If the left subtree is empty, the tree cannot contain
//the search key.
if(node.left == null) {
throw new KeyNotFoundInTableException();
}
//If this is the parent of the node to be removed, do
//the removal.
if(node.left.kvPair.key.equals(k)) {
node.left = lrMerge(node.left);
}
//Otherwise, recurse down another level.
else {
removeFromTree(k, node.left);
}
}
//Otherwise go to the right subtree.
else {
//If the right subtree is empty, the tree cannot contain
//the search key.
if(node.right == null) {
throw new KeyNotFoundInTableException();
}
//If this is the parent of the node to be removed, do
//the removal.
if(node.right.kvPair.key.equals(k)) {
node.right = lrMerge(node.right);
}
//Otherwise, recurse down another level.
else {
removeFromTree(k, node.right);
}
}
}
/**
* Merges the two subtrees of node prior to removal of
* the node from the tree.
*/
protected BSTreeNode lrMerge(BSTreeNode node) {
BSTreeNode mergedTrees = null;
//First two cases occur when one or both
//subtrees of the node to be deleted are empty.
if(node.left == null) {
mergedTrees = node.right;
}
else if(node.right == null) {
mergedTrees = node.left;
}
//Otherwise, merge the left and right subtrees
//and link the merged structure to the current
//node.
else {
addToTree(node.right, node.left);
mergedTrees = node.left;
}
return mergedTrees;
}
/**
* Uses in order tree traversal to construct a string containing all the
* key value pairs in the binary search tree.
*/
protected String treeString(BSTreeNode node) {
if(node == null) {
return "";
}
Entry lutEntry = node.kvPair;
String thisNode = "";
thisNode = lutEntry.key.toString();
thisNode += ":";
thisNode += lutEntry.value;
thisNode += ", ";
return treeString(node.left) + treeString(node.right) + thisNode;
}
}
测试文件在这里:
BinaryTreeLUTTest.java:
public class BinaryTreeLUTTest {
public static void main(String[] args) {
try {
BinaryTreeLUT myLUT = new BinaryTreeLUT();
myLUT.insert("Priscilla", new Integer(41));
myLUT.insert("Travis", new Integer(34));
myLUT.insert("Samuel", new Integer(28));
myLUT.insert("Helena", new Integer(39));
myLUT.insert("Andrew", new Integer(14));
myLUT.insert("Kay", new Integer(24));
myLUT.insert("John", new Integer(67));
System.out.println(myLUT);
myLUT.remove("Helena");
System.out.println(myLUT);
myLUT.remove("John");
System.out.println(myLUT);
myLUT.remove("Travis");
System.out.println(myLUT);
myLUT.remove("Samuel");
System.out.println(myLUT);
myLUT.remove("Andrew");
System.out.println(myLUT);
} catch (Exception e) {
System.out.println(e);
}
}
}