在二叉查找树中:
(01) 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(02) 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(03) 任意节点的左、右子树也分别为二叉查找树。
(04) 没有键值相等的节点(no duplicate nodes)。
直接上个码:
/**
* @注:泛型T必须是实现了Comparable接口。
*
* @author Linging
* @date:2019/2/16
* @param <T> /实现二叉搜索树的基本功能
*/
public class BSTree<T extends Comparable<T>> {
//树根节点
public BSTNode<T> mRoot;
//树节点类型
public class BSTNode<T extends Comparable<T>> {
private T key;
private BSTNode<T> parent;
private BSTNode<T> left;
private BSTNode<T> right;
public BSTNode(T key, BSTNode<T> parent, BSTNode<T> left, BSTNode<T> right){
this.key = key;
this.parent = parent;
this.left = left;
this.right = right;
}
public T getKey() {
return key;
}
}
public BSTree() {
this.mRoot = null;
}
public void insertNode(BSTree<T> bst, BSTNode<T> node) {
BSTNode<T> nodeParent = null; //要插入节点node的父节点
BSTNode<T> root = bst.mRoot; //初始指向根节点
int cmp; //判断是左子树还是右子树
//查找插入位置
while(root != null) {
nodeParent = root;
cmp = node.key.compareTo(root.key);
if(cmp < 0) {
root = root.left;
}else {
root = root.right;
}
}
node.parent = nodeParent;
if(nodeParent == null) { //没有树根的情况
bst.mRoot = node;
}else {
cmp = node.key.compareTo(nodeParent.key);
if(cmp < 0) {
nodeParent.left = node;
}else {
nodeParent.right = node;
}
}
}
//功能:插入节点
public void insert(T key) {
//构建节点b
BSTNode<T> b = new BSTNode<T>(key, null, null, null);
//插入节点b
if(b != null) {
insertNode(this,b);
}
}
//前序遍历
public void preOrder(BSTNode<T> tree) {
if(tree !=null) {
System.out.print(tree.key+" ");
preOrder(tree.left);
preOrder(tree.right);
}
}
//中序遍历
public void inOrder(BSTNode<T> tree) {
if(tree !=null) {
inOrder(tree.left);
System.out.print(tree.key+" ");
inOrder(tree.right);
}
}
//后续遍历
public void postOrder(BSTNode<T> tree) {
if(tree !=null) {
postOrder(tree.left);
postOrder(tree.right);
System.out.print(tree.key+" ");
}
}
//销毁二叉搜索树
public void dest(BSTNode<T> tree) {
if(tree == null)
return;
if(tree.left != null)
dest(tree.left);
if(tree.right != null)
dest(tree.right);
tree = null;
}
public void destroy() {
dest(mRoot);
mRoot = null;
}
//查找节点为key的节点
public BSTNode<T> find(BSTNode<T> node, T key) {
if(node == null)
return null;
int cmp = key.compareTo(node.key);
if(cmp < 0)
return find(node.left, key);
else if(cmp > 0)
return find(node.right, key);
else
return node;
}
public BSTNode<T> findNode(T key){
return find(mRoot, key);
}
//查找树中值最小的节点
public BSTNode<T> minNode(BSTNode<T> tree){
if(tree == null)
return null;
while(tree.left != null)
tree = tree.left;
return tree;
}
//查找树中值最大的节点
public BSTNode<T> maxNode(BSTNode<T> tree){
if(tree == null)
return null;
while(tree.right != null)
tree = tree.right;
return tree;
}
//返回x节点的后继节点
public BSTNode<T> successor(BSTNode<T> x) {
if(x == null)
return null;
// 如果x存在右孩子,则"x的后继结点"为 "以其右孩子为根的子树的最小结点"。
if (x.right != null)
return minNode(x.right);
// 如果x没有右孩子。则x有以下两种可能:
// (01) x是"一个左孩子",则"x的后继结点"为 "它的父结点"。
// (02) x是"一个右孩子",则查找"x的最低的父结点,并且该父结点要具有左孩子",找到的这个"最低的父结点"就是"x的后继结点"。
BSTNode<T> y = x.parent;
while ((y!=null) && (x==y.right)) {
x = y;
y = y.parent;
}
return y;
}
//返回x节点的前驱节点
public BSTNode<T> predecessor(BSTNode<T> x) {
if(x == null) return null;
// 如果x存在左孩子,则"x的前驱结点"为 "以其左孩子为根的子树的最大结点"。
if(x.left != null)
return maxNode(x.left);
// 如果x没有左孩子。则x有以下两种可能:
// (01) x是"一个右孩子",则"x的前驱结点"为 "它的父结点"。
// (01) x是"一个左孩子",则查找"x的最低的父结点,并且该父结点要具有右孩子",找到的这个"最低的父结点"就是"x的前驱结点"。
BSTNode<T> y = x.parent;
while((y != null) && (x == y.left)) {
x = y;
y = y.parent;
}
return y;
}
//删除树中节点z
public boolean remove(BSTree<T> tree, BSTNode<T> node){
if(tree == null)
return false;
//处理node节点有左右子树的情况
if(node.left != null && node.right != null) {
//获取node节点的前驱节点
BSTNode<T> predecessor = predecessor(node);
//将node节点的值替换为前驱节点的值,实现节点的“移动”
node.key = predecessor.key;
//把要删除的节点设置为前驱节点,其删除就是下面两种情况了
node = predecessor;
}
//将node只有一个孩子节点和没有孩子节点两种情况一起处理
//获取要删除节点node的孩子节点,可以是null,
BSTNode<T> child;
if(node.left != null)
child = node.left;
else
child = node.right;
//将孩子节点和父节点关联上
if(child != null)
child.parent = node.parent;
if(node.parent == null) //不存在父节点,node为根节点且只有左子树或者右子树
mRoot = child;
else if(node == node.parent.left) //存在父节点,且node为父节点的左孩子
node.parent.left = child;
else if(node == node.parent.right) //存在父节点,且node为父节点的右孩子
node.parent.right = child;
node = null;
return true;
}
public void delete(T key) {
BSTNode<T> node = findNode(key); //查找要删除的节点
if(node != null)
remove(this, node);
}
//打印二叉搜索树
public void print(BSTNode<T> tree, int height) {
if(tree != null) {
for(int i = 1; i <= height; i++)
System.out.print("-");
System.out.print(tree.key+"\n");
print(tree.left, height+1);
print(tree.right, height+1);
}
}
public static void main(String[] args) {
BSTree<Integer> bst = new BSTree<Integer>();
//依次插入节点2,4,5,1,3
bst.insert(2);
bst.insert(4);
bst.insert(5);
bst.insert(1);
bst.insert(3);
//打印二叉搜索树
bst.print(bst.mRoot, 1);
System.out.println();
//前序遍历
bst.preOrder(bst.mRoot); //2,1,4,3,5
System.out.println();
//中序遍历
bst.inOrder(bst.mRoot); //1,2,3,4,5
System.out.println();
//后续遍历
bst.postOrder(bst.mRoot); //1,3,5,4,2
System.out.println();
//查找节点9
System.out.println(bst.findNode(9)); // null
//返回节点1的后继节点
System.out.println(bst.successor(bst.findNode(1)).key); // 2
//返回节点5的前驱节点
System.out.println(bst.predecessor(bst.findNode(5)).key); //4
//树中值最小的节点
System.out.println(bst.minNode(bst.mRoot).key); // 1
//树中值最大的节点
System.out.println(bst.maxNode(bst.mRoot).key); // 5
//删除节点2
bst.delete(2);
bst.preOrder(bst.mRoot); //1,4,3,5
System.out.println();
bst.inOrder(bst.mRoot); //1,3,4,5
System.out.println();
bst.postOrder(bst.mRoot); //3,5,4,1
System.out.println();
//打印二叉搜索树
bst.print(bst.mRoot, 1);
System.out.println();
//销毁二叉搜索树
bst.destroy();
}
}
学习自:http://www.cnblogs.com/skywang12345/p/3576452.html
https://blog.youkuaiyun.com/isea533/article/details/80345507