/**
* 二叉树 不重复场景,重复场景再删除等不考虑
*
* @author dyh 171738906@qq.com
* @date 2018/02/28
*/
public class BSTree<T extends Comparable<T>> {
private BSNode<T> root;
/**
* 插入二叉树数据
*
* @param key
*/
public void insertTree(BSNode<T> node, T key) {
BSNode<T> addedBSNode = new BSNode<T>(key);
BSNode<T> parent = null;
BSNode<T> temp = node;
// 查找父节点
while (temp != null) {
parent = temp;
if (temp.compareTo(addedBSNode) > 0) {
temp = temp.getLeft();
} else {
temp = temp.getRight();
}
}
// 如果父节点为null,则为ROOT节点,需要重新赋值
if (parent == null) {
this.root = addedBSNode;
return;
}
addedBSNode.setParent(parent);
if (parent.compareTo(addedBSNode) > 0) {
parent.setLeft(addedBSNode);
} else {
parent.setRight(addedBSNode);
}
}
public void insertTree(T[] keys) {
for (int i = 0; i < keys.length; i++) {
insertTree(root, keys[i]);
}
}
public void insertTree(T key) {
insertTree(root, key);
}
/**
*
* @param node
* @param key
*/
public void removeBSNode(BSNode<T> node, T key) {
// 检查节点是否存在 (此处如果不想检索,可以讲T key 修改为 BSNode 对象传入)
BSNode<T> removeBSNode = searchBSNode(node, key);
if (removeBSNode == null) {
return;
}
// 如果该节点没有左子节点
if (removeBSNode.getRight() == null) {
transPlant(removeBSNode, removeBSNode.getLeft());
} else if (removeBSNode.getLeft() == null) {
transPlant(removeBSNode, removeBSNode.getRight());
} else {
// 有左右子节点,找出后驱值,并使用该节点替换
BSNode<T> successor = minBSNode(removeBSNode.getRight());
// 需要设置该节点的右子节点,后驱肯定没有左子节点
if (successor.getParent() != removeBSNode)
{
transPlant(successor, successor.getRight());
successor.setRight(removeBSNode.getRight());
successor.getRight().setParent(successor);
}
// 交换后驱与被移除的值
transPlant(removeBSNode, successor);
successor.setLeft(removeBSNode.getLeft());
successor.getLeft().setParent(successor);
}
}
/**
* 以一个节点替换另一个节点
*
* @param srcNode
* @param node
*/
private void transPlant(BSNode<T> srcNode, BSNode<T> node) {
if (srcNode.getParent() == null) {
this.root = node;
}
if (srcNode == srcNode.getParent().getLeft()) {
srcNode.getParent().setLeft(node);
} else {
srcNode.getParent().setRight(node);
}
if (node != null) {
node.setParent(srcNode.getParent());
}
}
/**
* 中序遍历 令: 前序、后序遍历跟打印key位置相关,不创建方法
*
* @param node
*/
public void inorderTreeWalk(BSNode<T> node) {
if (node == null) {
return;
}
inorderTreeWalk(node.getLeft());
System.out.print(node.getKey() + " ");
inorderTreeWalk(node.getRight());
}
inorderTreeWalk(root);
}
/**
* 取最小节点
*
* @param node
* @return
*/
public BSNode<T> minBSNode(BSNode<T> node) {
if (null == node || node.getLeft() == null) {
return node;
}
return minBSNode(node.getLeft());
}
public BSNode<T> minBSNode() {
return minBSNode(root);
}
/**
* 取最大节点
*
* @param node
* @return
*/
public BSNode<T> maxBSNode(BSNode<T> node) {
if (null == node || node.getRight() == null) {
return node;
}
return maxBSNode(node.getRight());
}
public BSNode<T> maxBSNode() {
return maxBSNode(root);
}
/**
* 查找等于某个key的节点
*
* @param node
* @param key
* @return
*/
public BSNode<T> searchBSNode(BSNode<T> node, T key) {
int res;
if (null == node || (res = node.getKey().compareTo(key)) == 0) {
return node;
}
if (res > 0) {
return searchBSNode(node.getLeft(), key);
} else {
return searchBSNode(node.getRight(), key);
}
}
/**
* 使用while方式进行查找
*
* @param node
* @param key
* @return
*/
public BSNode<T> iterativeSearchBSNode(BSNode<T> node, T key) {
int res;
while (null != node && ((res = node.getKey().compareTo(key)) != 0)) {
if (res > 0) {
node = node.getLeft();
} else {
node = node.getRight();
}
}
return node;
}
/**
* 查找后继节点,即大于当前节点的最小值
* 前驱方法就不实现了,同理
*
* @param node
* @return
*/
public BSNode<T> successorBSNode(BSNode<T> node) {
if (node == null) {
return null;
}
// 如果当前节点存在右子节点,则获取右子节点的最小节点
if (null != node.getRight()) {
return minBSNode(node.getRight());
}
BSNode<T> temp = node;
BSNode<T> parent = node.getParent();
while (parent != null && temp == parent.getRight()) {
temp = parent;
parent = parent.getParent();
}
return parent;
}
public class BSNode<TT extends Comparable<TT>> implements Comparable<BSNode<TT>> {
private TT key;
private BSNode<TT> parent;
private BSNode<TT> left;
private BSNode<TT> right;
private BSNode(TT key) {
this.key = key;
}
public int compareTo(BSNode<TT> o) {
return this.key.compareTo(o.getKey());
}
public TT getKey() {
return key;
}
public void setKey(TT key) {
this.key = key;
}
public BSNode<TT> getParent() {
return parent;
}
public void setParent(BSNode<TT> parent) {
this.parent = parent;
}
public BSNode<TT> getLeft() {
return left;
}
public void setLeft(BSNode<TT> left) {
this.left = left;
}
public BSNode<TT> getRight() {
return right;
}
public void setRight(BSNode<TT> right) {
this.right = right;
}
}
public BSNode<T> getRoot() {
return root;
}
public void setRoot(BSNode<T> root) {
this.root = root;
}
}
package com.dyh.algorithms.binarySortedTree;
public class BSTreeTest {
public static void main(String[] args) {
BSTree<Integer> bsTree = new BSTree<Integer>();
bsTree.insertTree(new Integer[] {20,15,25,5,22,10,45,1,35,50,30,40,32});
bsTree.inorderTreeWalk();
System.out.println();
System.out.println(bsTree.minBSNode().getKey());
System.out.println(bsTree.maxBSNode().getKey());
System.out.println(bsTree.searchBSNode(bsTree.getRoot(), 20).getKey());
System.out.println(bsTree.searchBSNode(bsTree.getRoot(), 21));
System.out.println(bsTree.successorBSNode(bsTree.getRoot().getRight().getRight().getLeft()).getKey());
System.out.println(bsTree.successorBSNode(bsTree.getRoot().getLeft().getLeft().getRight()).getKey());
bsTree.removeBSNode(bsTree.getRoot(), 25);
bsTree.inorderTreeWalk();
}
}