package algorithm.binarytree; import java.util.Arrays; import java.util.Stack; import util.ArrayUtil; import 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 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 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(20, 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); } private static void testDelete(BinTree binTree, int value) { binTree.delete(value); binTree.preOrder(); binTree.inOrder(); OutputUtil.outputLineSeparator(); } public static void main(String[] args) { test1(); } } package util; import java.util.Random; public class ArrayUtil { public static int[] generate(int n, int threshold) { return generate(n, threshold, true); } public static int[] generate(int n, int threshold, boolean isPos) { int[] ret = new int[n]; Random rand = new Random(); if(threshold <= 0) { for(int i = 0; i < n; i++) { ret[i] = rand.nextInt(); if(ret[i] < 0 && isPos) { ret[i] *= -1; } } } else { for(int i = 0; i < n; i++) { ret[i] = rand.nextInt() % threshold; if(ret[i] < 0 && isPos) { ret[i] *= -1; } } } return ret; } public static int[] generateInSeq(int n, int start) { int[] ret = new int[n]; for(int i = 0; i < n; i++) { ret[i] = start + i; } return ret; } public static void output(int data[]) { for(int i = 0; i < data.length; i++) { System.out.print(data[i] + " "); } System.out.println(); } public static int find(int data[], int value) { for(int i = 0; i < data.length; i++) { if(data[i] == value) { return i; } } return -1; } public static void swap(int data[], int i, int j) { int tmp = data[i]; data[i] = data[j]; data[j] = tmp; } } package util; public class OutputUtil { public static void output(char c, int size) { for(int i = 0; i < size; i++) { System.out.print(c); } System.out.println(); } public static void outputLineSeparator() { output('=', 60); } }