package com.e2u.tree; import java.util.Stack; import com.e2u.util.ArrayUtil; import com.e2u.util.OutputUtil; public class BinTree { private BinNode root = null; public BinTree() { } public BinTree(int data[]) { if(data == null || data.length == 0) { root = null; return; } root = buildInOrder(data, 0, data.length - 1); } private BinNode buildInOrder(int data[], int start, int end) { if(start > end) { return null; } int mid = (start + end) >> 1; BinNode lc = buildInOrder(data, start, mid - 1); BinNode rc = buildInOrder(data, mid + 1, end); return new BinNode(data[mid], lc, rc); } public BinNode getRoot() { return root; } public void setRoot(BinNode root) { this.root = root; } public void insert(BinNode parent, int value, boolean isLeft) { if(parent == null) { root = new BinNode(value); return; } if(isLeft) { parent.lc = new BinNode(value); } else { parent.rc = new BinNode(value); } } public BinNode insert(int value) { if(root == null) { root = new BinNode(value); return root; } BinNode t = root; BinNode parent = null; do { parent = t; if(value <= t.value) { t = t.lc; } else { t = t.rc; } }while(t != null); BinNode insertNode = new BinNode(value); if(value <= parent.value) { parent.lc = insertNode; } else { parent.rc = insertNode; } return insertNode; } public void delete(int value) { //Does this tree has nodes? if(root == null) { return; } BinNode parent = null; BinNode t = root; //Find the node with the value that same to the parameter "value" while(t != null) { if(value == t.value) { break; } else if(value < t.value) { parent = t; t = t.lc; } else { parent = t; t = t.rc; } } //There's no node with parameter "value" if(t == null) { return; } //We find the node with value of input parameter "value" //(1) Replace its value with biggest left child node's value, then delete that node //(2) If there's no any left children of this node (t), make the parent of this node //point to its right child directly //Biggest left child BinNode biggestLc = t.lc; //No left child if(biggestLc == null) { //t is the root node if(parent == null) { root = t.rc; } else { if(t == parent.lc) { parent.lc = t.rc; } else { parent.rc = t.rc; } } return; } //The parent of biggest left child node BinNode parentOfBiggestLc = t; //The biggest left child should be the rightmost node of t.lc while(biggestLc.rc != null) { parentOfBiggestLc = biggestLc; biggestLc = biggestLc.rc; } //Find the biggest left child, replace the value of node t with its value, then delete this node t.value = biggestLc.value; //The left child of t has no left child if(t.lc == biggestLc) { t.lc = biggestLc.lc; } else { parentOfBiggestLc.rc = biggestLc.lc; } } public void preOrder() { preOrder(new OutputVisitor()); System.out.println(); } public void preOrder(Visitor visitor) { if(root != null) { preOrderHelper(root, visitor); } } private void preOrderHelper(BinNode t, Visitor visitor) { visitor.visit(t); if(t.lc != null) { preOrderHelper(t.lc, visitor); } if(t.rc != null) { preOrderHelper(t.rc, visitor); } } public void preOrderStack() { preOrderStack(new OutputVisitor()); System.out.println(); } public void preOrderStack(Visitor visitor) { BinNode t = root; Stack<BinNode> s = new Stack<BinNode>(); while(t != null || !s.empty()) { while(t != null) { visitor.visit(t); s.push(t); t = t.lc; } t = s.pop().rc; } } public void inOrder() { inOrder(new OutputVisitor()); System.out.println(); } public void inOrder(Visitor visitor) { if(root != null) { inOrderHelper(root, visitor); } } private void inOrderHelper(BinNode t, Visitor visitor) { if(t.lc != null) { inOrderHelper(t.lc, visitor); } visitor.visit(t); if(t.rc != null) { inOrderHelper(t.rc, visitor); } } public void inOrderStack() { inOrderStack(new OutputVisitor()); System.out.println(); } public void inOrderStack(Visitor visitor) { BinNode t = root; Stack<BinNode> s = new Stack<BinNode>(); while(t != null || !s.empty()) { while(t != null) { s.push(t); t = t.lc; } t = s.pop(); visitor.visit(t); t = t.rc; } } public void postOrder() { postOrder(new OutputVisitor()); System.out.println(); } public void postOrder(Visitor visitor) { if(root != null) { postOrderHelper(root, visitor); } } private void postOrderHelper(BinNode t, Visitor visitor) { if(t.lc != null) { postOrderHelper(t.lc, visitor); } if(t.rc != null) { postOrderHelper(t.rc, visitor); } visitor.visit(t); } public void postOrderStack() { postOrderStack(new OutputVisitor()); System.out.println(); } public void postOrderStack(Visitor visitor) { BinNode t = root; Stack<BinNode> s = new Stack<BinNode>(); BinNode p = null; while(t != null || !s.empty()) { while(t != null) { s.push(t); t = t.lc; } p = null; t = s.peek(); while(p == t.rc) { t = s.pop(); visitor.visit(t); p = t; if(s.isEmpty()) { return; } t = s.peek(); } t = t.rc; } } public void findPath(BinNode t, int sum, Stack st, boolean flag) { if(t == null) { return; } st.push(t); if(t.value == sum) { System.out.println(st); } findPath(t.lc, sum - t.value, st, true); // System.out.println("before rc, t = " + t.value + ", st = " + st); findPath(t.rc, sum - t.value, st, true); // System.out.println("after rc, t = " + t.value + ", st = " + st); st.pop(); if(!flag) { findPath(t.lc, sum, st, false); findPath(t.rc, sum, st, false); } } public static class BinNode { public int value = Integer.MIN_VALUE; public BinNode lc = null; public BinNode rc = null; public BinNode(int value, BinNode left, BinNode right) { this.value = value; this.lc = left; this.rc = right; } public BinNode(int value) { this(value, null, null); } public String toString() { return String.valueOf(value); } } public static interface Visitor { public void visit(BinNode node); } public static class OutputVisitor implements Visitor { public void visit(BinNode node) { System.out.print(node.value + " "); System.out.flush(); } } public static BinTree buildTree(int data[]) { BinTree binTree = new BinTree(); for(int i = 0; i < data.length; i++) { binTree.insert(data[i]); } return binTree; } public static void test1() { // int[] data = ArrayUtil.generate(20, 101); // int[] data = ArrayUtil.generateInSeq(4, 1); int[] data = {4, 3, 5, 2, 1}; // Arrays.sort(data); ArrayUtil.output(data); OutputUtil.outputLineSeparator(); BinTree binTree = new BinTree(data); // BinTree binTree = buildTree(data); binTree.preOrder(); binTree.preOrderStack(); OutputUtil.outputLineSeparator(); binTree.inOrder(); binTree.inOrderStack(); OutputUtil.outputLineSeparator(); binTree.postOrder(); binTree.postOrderStack(); OutputUtil.outputLineSeparator(); // testDelete(binTree, data[5]); // testDelete(binTree, data[6]); // testDelete(binTree, data[7]); // testDelete(binTree, 15); binTree.findPath(binTree.getRoot(), 7, new Stack(), false); } private static void testDelete(BinTree binTree, int value) { binTree.delete(value); binTree.preOrder(); binTree.inOrder(); OutputUtil.outputLineSeparator(); } public static void main(String[] args) { test1(); } }