package Alg; public class BSTreeNode { private BSTreeNode leftChild = null; private BSTreeNode rightChild = null; private BSTreeNode parent = null; private int value = Integer.MIN_VALUE; public static BSTreeNode createNode(int val) { return new BSTreeNode(val); } private BSTreeNode(int val) { leftChild = null; rightChild = null; parent = null; value = val; } public BSTreeNode search(int val) { if (val == value) return this; if (val > value ) { if (this.getRightChild() != null) return this.getRightChild().search(val); } else { if (this.getLeftChild() != null) return this.getLeftChild().search(val); } return this; } public boolean isLeaf() { if (getLeftChild() == null && getRightChild() == null) return true; return false; } public boolean isRoot() { if (getParent() == null) return true; return false; } public BSTreeNode getLeftChild() { return leftChild; } public void setLeftChild(BSTreeNode leftChild) { this.leftChild = leftChild; } public BSTreeNode getRightChild() { return rightChild; } public void setRightChild(BSTreeNode rightChild) { this.rightChild = rightChild; } public BSTreeNode getParent() { return parent; } public void setParent(BSTreeNode parent) { this.parent = parent; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } }
package
Alg;public class BSTree { private
BSTreeNode root = null; //树根节点 private
int count = 0; //树的节点数 public
int getCount() { return
count; } public
enum MatchType {E, GE, LE}; /** * 根据值进行搜索 * @param val 匹配值 * @param matchType 匹配方式 E为严格相等匹配,GE为大于等于匹配,LE为小于等于匹配 * @return 匹配模式为E时,如果没有找到匹配项,返回null,否则返回匹配到的节点 * 匹配模式为GE时,如果匹配到数据,返回匹配到的数据,否则返回大于该数据的最小节点 * 匹配模式为LE时,如果匹配到数据,返回匹配到的数据,否则返回小于该数据的最大节点 */ public
BSTreeNode search(int
val, MatchType matchType) { BSTreeNode n = search(val); if
(n == null) return
null; if
(n.getValue() == val) return
n; switch
(matchType) { case
LE: if
(n.getValue() < val) return
n; return
getLittleSmaller(n); case
GE: if
(n.getValue() > val) return
n; return
getLittleBigger(n); default: } return
null; } private
BSTreeNode search(int
val) { if
(root == null) return
null; return
search(root, val); } /** * 获取距离该值最近的节点 * @param n * @param val * @return */ private
BSTreeNode search(BSTreeNode n, int
val) { int
v = n.getValue(); if
(v == val) return
n; else
if (v > val) { if
(n.getLeftChild() == null) return
n; return
search(n.getLeftChild(), val); } if
(n.getRightChild() == null) return
n; return
search(n.getRightChild(), val); } /** * 进行插入操作 * @param val */ public
void insert(int
val) { if
(root == null) { root = BSTreeNode.createNode(val); count++; return; } BSTreeNode x = search(val); if
(x.getValue() == val) return; BSTreeNode n = BSTreeNode.createNode(val); count++; if
(x.getValue() < val) x.setRightChild(n); else x.setLeftChild(n); n.setParent(x); } /** * 删除值 * @param val */ public
void delete(int
val) { if
(root == null) return; BSTreeNode x = root.search(val); if
(x.getValue() != val) return; count++; //当为叶子节点时从父节点将该节点的连接删除 if
(x.isLeaf()) { BSTreeNode p = x.getParent(); if
(p.getLeftChild() == x) p.setLeftChild(null); else p.setRightChild(null); } BSTreeNode lc = x.getLeftChild(); BSTreeNode rc = x.getRightChild(); //如果具有两个非空子树,或者从左子树中取得最大的节点代替当前节点 //或者从右子树取得最小节点代替当前节点 //然后删除代替的节点 if
(lc != null
&& rc != null) { BSTreeNode lr = getRightMostNode(lc); BSTreeNode rr = getLeftMostNode(rc); //如果是叶节点则可以简单替换节点进行处理,否则要替换后进行再次替换 if
(lr.isLeaf()) { x.setValue(lr.getValue()); BSTreeNode rp = lr.getParent(); rp.setRightChild(null); return
; } else
if (rr.isLeaf()) { x.setValue(rr.getValue());; BSTreeNode lp = rr.getParent(); lp.setLeftChild(null); return
; } else
{ //调换两个节点,并将删除转换为只有一个子树的情况 x.setValue(lr.getValue()); x = lr; } } //如果只有一个子树(左子树或右子树),则用子树中的根代替当前节点 BSTreeNode p = x.getParent(); if
(lc != null) { if
(p.getLeftChild() == x) p.setLeftChild(lc); else p.setRightChild(lc); return
; } if
(rc != null) { if
(p.getLeftChild() == x) p.setLeftChild(rc); else p.setRightChild(rc); } } /** * 以升序方式打印树中节点,实际就是中根的树的访问次序 */ public
void printInAscOrd() { if
(root == null) System.out.println("没有数据"); printInOrder(root); } /** * 将二叉树转换为升序排列的数组 * @return 返回升序排序后的数组 */ public
BSTreeNode[] getAscOrderArray() { BSTreeNode[] ary = new
BSTreeNode[count]; int
pos = fillArrayInOrd(ary, 0, root); if
(pos != count) System.out.println("构造数组出错"); return
ary; } private
int fillArrayInOrd(BSTreeNode[] ary, int
pos, BSTreeNode root) { int
npos = pos; if
(root.getLeftChild() != null) { npos = fillArrayInOrd(ary, npos, root.getLeftChild()); } ary[npos] = root; npos++; if
(root.getRightChild() != null) { npos = fillArrayInOrd(ary, npos, root.getRightChild()); } return
npos; } /** * 获取大于当前节点的最小节点 * @param x * @return 如果没有大于该节点的节点,则返回null */ private
BSTreeNode getLittleBigger(BSTreeNode x) { BSTreeNode rc = x.getRightChild(); if
(rc != null) { return
getLeftMostNode(rc); } else
{ //回溯祖先节点,取得第一个令该节点为左子树节点的祖先节点 BSTreeNode p = x.getParent(); BSTreeNode s = x; while
(p != null) { if
(p.getLeftChild() == s) break; s = p; p = p.getParent(); } return
p; } } private
BSTreeNode getLittleSmaller(BSTreeNode x) { BSTreeNode lc = x.getLeftChild(); if
(lc != null) { return
getRightMostNode(lc); } else
{ //回溯祖先节点,取得第一个令该节点为左子树节点的祖先节点 BSTreeNode p = x.getParent(); BSTreeNode s = x; while
(p != null) { if
(p.getRightChild() == s) break; s = p; p = p.getParent(); } if
(p != null) return
p; } return
null; } private
BSTreeNode getLeftMostNode(BSTreeNode x) { while
(x.getLeftChild() != null) { x = x.getLeftChild(); } return
x; } private
BSTreeNode getRightMostNode(BSTreeNode x) { while
(x.getRightChild() != null) { x = x.getRightChild(); } return
x; } private
void printInOrder(BSTreeNode n) { if
(n.getLeftChild() != null) printInOrder(n.getLeftChild()); printNode(n); if
(n.getRightChild() != null) printInOrder(n.getRightChild()); } private
void printNode(BSTreeNode n) { System.out.print("["
+ n.getValue() + "]"); } private
void checkTreeValidation() throws
Exception { BSTreeNode[] ary = this.getAscOrderArray(); for
(int i = 0; i < ary.length; i++) { if
(ary[i].getValue() > ary[i + 1].getValue()) { throw
new Exception("二叉树出现错误"); } } } public
static BSTree buildRandomTree1() { BSTree tree = new
BSTree(); try
{ tree.insert(8569); tree.insert(7556); tree.insert(3421); tree.insert(5665); tree.insert(5169); tree.insert(9189); tree.insert(5656); tree.insert(6691); tree.insert(6932); tree.insert(3511); tree.insert(4269); tree.insert(3556); tree.checkTreeValidation(); return
tree; } catch
(Exception e) { e.printStackTrace(); return
null; } } public
static BSTree buildRandomTree2() { BSTree tree = new
BSTree(); try
{ tree.insert(53); tree.insert(12); tree.insert(27); tree.insert(99); tree.insert(46); tree.insert(5); tree.insert(38); tree.checkTreeValidation(); return
tree; } catch
(Exception e) { e.printStackTrace(); return
null; } } public
static void testInsertCase1() { BSTree tree = buildRandomTree1(); if
(tree == null) System.out.println("构造二叉树出错"); tree.printInAscOrd(); } public
static void testInsertCase2() { BSTree tree = buildRandomTree2(); if
(tree == null) System.out.println("构造二叉树出错"); tree.printInAscOrd(); } public
static void testGetArray() { BSTree tree = buildRandomTree2(); if
(tree == null) System.out.println("构造二叉树出错"); BSTreeNode[] ary = tree.getAscOrderArray(); for
(int i = 0; i < ary.length; i++) { System.out.print("["); System.out.print(ary[i].getValue()); System.out.print("]"); } } public
static void testGetLittleBigger(){ BSTree tree = buildRandomTree2(); if
(tree == null) System.out.println("构造二叉树出错"); tree.printInAscOrd(); System.out.println(""); BSTreeNode[] ary = tree.getAscOrderArray(); for
(int i = 0; i < ary.length - 1; i++) { BSTreeNode n = ary[i]; BSTreeNode b = tree.getLittleBigger(n); System.out.println("当前数值"
+ n.getValue() +"."
+ "较大数值为"
+ b.getValue()); if
(b.getValue() != ary[i + 1].getValue()) System.out.println("出现错误"); else System.out.println("正确"); } } public
static void testGetLittleSmaller() { BSTree tree = buildRandomTree2(); if
(tree == null) System.out.println("构造二叉树出错"); tree.printInAscOrd(); System.out.println(""); BSTreeNode[] ary = tree.getAscOrderArray(); for
(int i = ary.length - 1; i > 0; i--) { BSTreeNode n = ary[i]; BSTreeNode s = tree.getLittleSmaller(n); System.out.println("当前数值"
+ n.getValue() +"."
+ "较小数值为"
+ s.getValue()); if
(s.getValue() != ary[i - 1].getValue()) System.out.println("出现错误"); else System.out.println("正确"); } } } |
原文:http://www.cnblogs.com/northhurricane/p/3576413.html