二叉排序树(BinarySortTree),又称二叉查找树、二叉搜索树。它或者是一棵空树;或者是具有下列性质的二叉树:若左子树不空,则左子树上所有结点的值均小于它的根结点的值;若右子树不空,则右子树上所有结点的值均大于它的根结点的值;左、右子树也分别为二叉排序树。若子树为空,查找不成功。
package com.gloomy.Tree;
import java.util.ArrayDeque;
import java.util.Comparator;
import java.util.Queue;
import java.util.Stack;
/**
* 二叉树的实现
*
* @author 过路的守望
*
*/
public class BinaryTree {
private static class TreeNode implements Comparable<TreeNode> {
/*
* 节点值
*/
int val;
/*
* 节点名称
*/
String label;
/*
* 节点左右儿子
*/
TreeNode left;
TreeNode right;
/*
* 自然顺序比较
*/
@Override
public int compareTo(TreeNode o) {
return this.val - o.val;
}
public TreeNode(int val, String label) {
this.val = val;
this.label = label;
}
}
/*
* 根节点
*/
private TreeNode root;
/*
* 自定义比较器
*/
private Comparator comparator;
/**
* 构造器
*/
public BinaryTree() {
}
public BinaryTree(TreeNode root) {
this.root = root;
}
public BinaryTree(TreeNode root, Comparator<TreeNode> comparator) {
this(root);
this.comparator = comparator;
}
public static void main(String[] args) {
TreeNode A = new TreeNode(1, "A");
TreeNode B = new TreeNode(2, "B");
TreeNode C = new TreeNode(3, "C");
TreeNode D = new TreeNode(4, "D");
TreeNode E = new TreeNode(5, "E");
TreeNode F = new TreeNode(6, "F");
TreeNode G = new TreeNode(7, "G");
TreeNode H = new TreeNode(8, "H");
TreeNode I = new TreeNode(9, "I");
TreeNode J = new TreeNode(10, "J");
TreeNode K = new TreeNode(11, "K");
TreeNode L = new TreeNode(12, "L");
TreeNode M = new TreeNode(13, "M");
TreeNode N = new TreeNode(14, "N");
BinaryTree binaryTree = new BinaryTree(G);
binaryTree.insert(C);
binaryTree.insert(B);
binaryTree.insert(E);
binaryTree.insert(F);
binaryTree.insert(E, binaryTree.root);
binaryTree.insert(I, binaryTree.root);
binaryTree.insert(A);
binaryTree.insert(D);
binaryTree.insert(J);
binaryTree.insert(H);
binaryTree.insert(K);
binaryTree.insert(L, binaryTree.root);
binaryTree.insert(M, binaryTree.root);
binaryTree.insert(N, binaryTree.root);
binaryTree.remove(G);
binaryTree.remove(H);
binaryTree.remove(I, binaryTree.root);
binaryTree.remove(J, binaryTree.root);
System.out.println(binaryTree.root.val);
System.out.println(binaryTree.findMax().val);
System.out.println(binaryTree.findMin().val);
System.out.println("先序遍历:");
binaryTree.preOrder();
System.out.println("中序遍历:");
binaryTree.inOrder();
System.out.println("后序遍历:");
binaryTree.postOrder();
System.out.println("层序遍历:");
binaryTree.levelOrder();
}
/**
*
* @param node
* 树中是否含有此节点
* @return
*/
public boolean contains(TreeNode node) {
if (root == null) {
return false;
}
TreeNode currentNode = root;
while (node.val != currentNode.val) {
/*
* node的值大于currentNode的值,在currentNode的右子树中寻找
*/
if (node.compareTo(currentNode) > 0) {
currentNode = currentNode.right;
/*
* 若果currentNode为空,则说明树中不包含此节点
*/
if (currentNode == null) {
return false;
}
}
/*
* node的值小于currentNode的值,在currentNode的左子树中寻找
*/
if (node.compareTo(currentNode) < 0) {
currentNode = currentNode.left;
if (currentNode == null) {
return false;
}
}
}
return true;
}
/*
* 清空树
*/
public void makeEmpty() {
root = null;
}
/**
* 寻找树中最大的节点
*/
public TreeNode findMax() {
if (root == null) {
return null;
}
/*
* 一直延伸到最右叶子节点
*/
TreeNode currentNode = root;
while (currentNode.right != null) {
currentNode = currentNode.right;
}
return currentNode;
}
/**
* 寻找树中最小的节点
*
* @return
*/
public TreeNode findMin() {
if (root == null) {
return null;
}
/*
* 一直延伸到最左叶子节点
*/
TreeNode currentNode = root;
while (currentNode.left != null) {
currentNode = currentNode.left;
}
return currentNode;
}
/**
* 向树中插入该节点元素
*
* @param node
*/
public void insert(TreeNode node) {
/*
* 如果树为空,此节点作为根节点
*/
if (root == null) {
root = node;
return;
}
/*
* 如果树中已存在此节点,直接返回
*/
if (contains(node)) {
return;
}
TreeNode currentnNode = root;
/*
* 记录上一个节点
*/
TreeNode parentNode = root;
while (node.val != currentnNode.val) {
parentNode = currentnNode;
/*
* 到右子树中寻找node所在位置
*/
if (node.compareTo(currentnNode) > 0) {
currentnNode = currentnNode.right;
if (currentnNode == null) {
parentNode.right = node;
return;
}
}
/*
* 到左子树中寻找node所在位置
*/
else {
currentnNode = currentnNode.left;
if (currentnNode == null) {
parentNode.left = node;
return;
}
}
}
}
/**
* 递归插入节点
*
* @param node
*/
public TreeNode insert(TreeNode node, TreeNode root) {
/*
* 树为空,插入节点作为根节点
*/
if (root == null) {
root = node;
return root;
}
/*
* 向右子树插入
*/
if (node.compareTo(root) > 0) {
root.right = insert(node, root.right);
}
/*
* 向左子树插入
*/
if (node.compareTo(root) < 0) {
root.left = insert(node, root.left);
}
/*
* 节点已在树中,不做任何处理
*/
else {
}
return root;
}
/**
* 删除树中的节点
*
* @param node
*/
public void remove(TreeNode node) {
/*
* 如果树中不含此节点,直接返回
*/
if (!contains(node)) {
return;
}
/*
* @parentNode 待删除节点的父节点
*
* @currentNode 待删除节点
*/
TreeNode parentNode = root;
TreeNode currentNode = root;
/*
* 记录待删除节点时父节点的左儿子还是右儿子
*/
boolean isRightChild = false;
/*
* 找到待删除节点
*/
while (node.val != currentNode.val) {
parentNode = currentNode;
if (node.compareTo(currentNode) > 0) {
currentNode = currentNode.right;
isRightChild = true;
}
if (node.compareTo(currentNode) < 0) {
currentNode = currentNode.left;
isRightChild = false;
}
}
/*
* 删除节点分四种情形: 1、待删除节点为叶子节点
*/
if (currentNode.left == null && currentNode.right == null) {
if (currentNode == root) {
root = null;
}
if (isRightChild) {
parentNode.right = node;
} else {
parentNode.left = node;
}
return;
}
/*
* 2、待删除节点只有右子树
*/
if (currentNode.left == null && currentNode.right != null) {
if (currentNode == root) {
root = root.right;
}
if (isRightChild) {
parentNode.right = currentNode.right;
} else {
parentNode.left = currentNode.right;
}
return;
}
/*
* 3、待删除节点只有左子树
*/
if (currentNode.left != null && currentNode.right == null) {
if (currentNode == root) {
root = root.left;
return;
}
if (isRightChild) {
parentNode.right = currentNode.left;
} else {
parentNode.left = currentNode.right;
}
return;
}
/*
* 4、待删除节点包含左右子树
*/
else {
/*
* 找到待删除节点右子树中的最小元素来替代node
*/
TreeNode replaceNode = replaceTreeNode(node);
replaceNode.left = currentNode.left;
replaceNode.right = currentNode.right;
if (currentNode == root) {
root = replaceNode;
return;
}
if (isRightChild) {
parentNode.right = replaceNode;
} else {
parentNode.left = replaceNode;
}
}
}
/**
*
* @param node
* 找到node节点的右子树中的最小元素节点来替代node
* @return
*/
private TreeNode replaceTreeNode(TreeNode node) {
/*
* 最左叶子节点的根
*/
TreeNode parentNode = node;
TreeNode currentNode = node.right;
/*
* 找到最左叶子节点
*/
while (currentNode.left != null) {
parentNode = currentNode;
currentNode = currentNode.left;
}
/*
* 把最左叶子节点的右子树衔接到其父节点
*/
if (parentNode == node) {
parentNode.right = currentNode.right;
} else {
parentNode.left = currentNode.right;
}
return currentNode;
}
/**
*
* @param node
* 待删除节点
* @param root
* 根节点
*/
public TreeNode remove(TreeNode node, TreeNode root) {
/*
* 根节点为空,自然不含node节点返回
*/
if (root == null) {
return null;
}
/*
* 新的根为右儿子
*/
if (node.compareTo(root) > 0) {
root.right = remove(node, root.right);
}
/*
* 新的根为左儿子
*/
else {
root.left = remove(node, root.left);
}
if (node.compareTo(root) == 0) {
/*
* 待删除节点含左右儿子
*/
if (root.left != null && root.right != null) {
/*
* 将右子树中最小节点的值赋给待删除节点,然后删除右子树的最小节点
*/
TreeNode replaceNode = findMin(root.right);
root.val = replaceNode.val;
root.right = remove(replaceNode, root.right);
} else {
root = (root.left != null) ? root.left : root.right;
}
}
return root;
}
/*
* 寻找指定子树中的最小元素
*/
public TreeNode findMin(TreeNode root) {
if (root == null) {
return null;
}
TreeNode currentNode = root;
while (currentNode.left != null) {
currentNode = currentNode.left;
}
return currentNode;
}
/**
* 非递归先序遍历二叉树
*/
public void preOrder() {
if (root == null) {
return;
}
TreeNode currentNode = root;
Stack<TreeNode> stack = new Stack<BinaryTree.TreeNode>();
stack.push(root);
while (!stack.isEmpty()) {
currentNode = stack.pop();
System.out.print(currentNode.val + " ");
/*
* 先进后出,先将右子树压栈
*/
if (currentNode.right != null) {
stack.push(currentNode.right);
}
if (currentNode.left != null) {
stack.push(currentNode.left);
}
}
System.out.println();
}
/**
* 非递归中序遍历
*/
public void inOrder() {
if (root == null) {
return;
}
Stack<TreeNode> stack = new Stack<BinaryTree.TreeNode>();
TreeNode currentNode = root;
/*
* 当栈为空并且currentNode为空时说明处理完所有节点
*/
while (currentNode != null || !stack.isEmpty()) {
while (currentNode != null) {
stack.push(currentNode);
currentNode = currentNode.left;
}
/*
* 处理根后处理右子树
*/
currentNode = stack.pop();
System.out.print(currentNode.val + " ");
currentNode = currentNode.right;
}
System.out.println();
}
/**
* 非递归后序遍历
*/
public void postOrder() {
if (root == null) {
return;
}
Stack<TreeNode> stack = new Stack<BinaryTree.TreeNode>();
TreeNode currentNode = root;
TreeNode pre = null;
while (currentNode != null || !stack.isEmpty()) {
while (currentNode != null) {
stack.push(currentNode);
currentNode = currentNode.left;
}
currentNode = stack.peek();
/*
* 当前节点的右子树为空或已访问过就将当前节点出栈
*/
while (currentNode.right == null || currentNode.right == pre) {
System.out.print(currentNode.val + " ");
pre = currentNode;
stack.pop();
if (stack.isEmpty()) {
System.out.println();
return;
}
currentNode = stack.peek();
}
/*
* 当前节点的右子树非空或者为处理则处理其右子树
*/
currentNode = currentNode.right;
}
}
/**
* 层序遍历
*/
public void levelOrder() {
if (root == null) {
return;
}
TreeNode currentNode = root;
Queue<TreeNode> queue = new ArrayDeque<BinaryTree.TreeNode>();
queue.offer(root);
while (!queue.isEmpty()) {
currentNode = queue.poll();
System.out.print(currentNode.val + " ");
if (currentNode.left != null) {
queue.offer(currentNode.left);
}
if (currentNode.right != null) {
queue.offer(currentNode.right);
}
}
System.out.println();
}
}