二叉搜索树是一种特殊的二叉树:
二叉搜索树也叫作二叉排序树、二叉查找树、有序二叉树、、、满足以下性质:
1.对于每个节点,其左子节点要么为空,要么值小于该节点值。
2.对于每个节点,其右子节点要么为空,要么值大于该节点值。
3.没有键值相等的点。
通俗的归纳一下性质,二叉查找树中每个节点的值都大于其左子节点,小于其右子节点(如果左右子节点存在的话)。所以二叉查找树中每个节点的左边,整棵左树都是小于它的节点;右边,整棵右树都是大于它的节点。
例如:
直接上代码:
package com.hc.test.Tree;
/**
* 创建时间:2017年12月1日 下午1:52:06 项目名称:Test
*
* @author hc
* @version 1.0 文件名称:BinaryTree.java 类说明: 二叉搜索树实现
*/
public class BinarySearchTree {
// 根节点
private Node root;
//寻找
public Node find(int key) {
Node current = root;
while (current.iData != key) {
if (key < current.iData)
current = current.leftChild;
else
current = current.rightChild;
if (current == null) {
return null;
}
}
return current;
}
//插入
public void insert(int id) {
Node newNode = new Node(id, null, null);
if (root == null)
root = newNode;
else {
Node current = root;
Node parent;
while (true) {
parent = current;
if (id < current.iData) {
current = current.leftChild;
if (current == null) {
parent.leftChild = newNode;
return;
}
} else {
current = current.rightChild;
if (current == null) {
parent.rightChild = newNode;
return;
}
}
}
}
}
//中序变量
public void inOrder(Node node){
if(node!=null){
//调用自身遍历节点的左子树
inOrder(node.leftChild);
//访问自身
System.out.print(node.iData+" ");
//调用自身遍历节点的右子树
inOrder(node.rightChild);
}
}
//前序遍历
public void preOrder(Node node){
if(node!=null){
//调用自身
System.out.print(node.iData+" ");
//调用自身遍历节点的左子树
preOrder(node.leftChild);
//调用自身遍历节点的右子树
preOrder(node.rightChild);
}
}
//后序遍历
public void postOrder(Node node){
if(node != null){
//调用自身遍历节点的左子树
postOrder(node.leftChild);
//调用自身遍历节点的右子树
postOrder(node.rightChild);
//调用自身
System.out.print(node.iData+" ");
}
}
//查找最小节点
public Node minNode(){
Node current,last = null;
current = root;
while(current != null){
last = current;
current =current.leftChild;
}
return last;
}
//查找最大几点
public Node maxNode(){
Node current,last = null;
current=root;
while(current != null){
last = current;
current =current.rightChild;
}
return last;
}
//删除
public boolean delete(int key) {
//先找到该节点再删除
Node current = root;
Node parent =root;
boolean isLeftChild = true;
//查找该点
while(current.iData != key){
parent = current;
if(key<current.iData){
isLeftChild=true;
current = current.leftChild;
}else{
isLeftChild=false;
current =current.rightChild;
}
if(current==null){
return false;
}
}
//该点为叶子节点
if(current.leftChild==null && current.rightChild==null){
if(current ==root){
root =null;
}else if (isLeftChild){
parent.leftChild=null;
}else{
parent.rightChild=null;
}
}else if(current.rightChild == null){
//只有右子节点
if(current ==root)
root = current.leftChild;
else if (isLeftChild)
parent.leftChild = current.leftChild;
else
parent.rightChild =current.leftChild;
}else if(current.leftChild==null){
//只有左子节点
if(current==root)
root =current.rightChild;
else if(isLeftChild)
parent.leftChild = current.rightChild;
else
parent.rightChild = current.rightChild;
}else{
//该节点有两个子节点
Node successor= getSuccessor(current);
if(current ==root)
root = successor;
else if(isLeftChild)
parent.leftChild=successor;
else
parent.rightChild=successor;
successor.leftChild =current.leftChild;
}
return true;
}
//查找后继
private Node getSuccessor(Node delNode){
Node successorParent = delNode;
Node successor = delNode;
Node current= delNode.rightChild;
while(current != null){
successorParent = successor;
successor =current;
current =current.leftChild;
}
if(successor != delNode.rightChild){
successorParent.leftChild = successor.rightChild;
successor.rightChild =delNode.rightChild;
}
return successor;
}
public class Node {
int iData;
Node leftChild;
Node rightChild;
public void displayNode() {
System.out.println(this.iData+" ");
}
public Node(int iData,Node leftChild, Node rightChild) {
super();
this.iData = iData;
this.leftChild = leftChild;
this.rightChild = rightChild;
}
public Node() {
}
}
}
附录:
查找资料的时候发现一博主做的模拟工具:
http://zh.visualgo.net/zh/bst
参考:
1. java数据结果和算法
2.博客 http://blog.youkuaiyun.com/chen_zhang_yu/article/details/52412510