二叉查找树(Binary Search Tree)具有以下基本性质:
1.若它的左子树不空,则左子树上所有结点的值均小于它的根节点的值;
2.若它的右子树不空,则右子树上所有结点的值均大于它的根节点的值;
3.它的左右子树也分别为二叉排序树。
通常采取二叉链表作为二叉排序树的存储结构。在java中构造了如下的记node类来代表单个节点:
public class BinaryNode {
AnyType data;
BinaryNode left;
BinaryNode right;
public BinaryNode(AnyType newData){
this(newData, null, null);
}
public BinaryNode(AnyType newData, BinaryNode lt, BinaryNode rt){
data=newData;
left=lt;
right=rt;
}
}
向一个二叉查找树b中插入一个节点s的算法:
1.若b是空树,则将s所指节点作为根节点插入,否则:
2.若s.data等于b的根节点的数据值,则返回,否则:
3.若s.data小于b的根节点的数据值,则把s所指节点插入到左子树中,否则:
4.把s所指节点插入到右子树中。
实现插入操作的代码如下:
public boolean insert(AnyType element){
if(root==null){
root=new BinaryNode(element);
size++;
return true;
}
else return insert(element,root);
}
public boolean insert(AnyType element, BinaryNode node){
if(element.compareTo(node.data)<0){
//Operate on left-child.
if(node.left==null){
BinaryNode newNode=new BinaryNode(element);
node.left=newNode;
size++;
return true;
}
else{
return insert(element,node.left);
}
}
else{
//Operate on right-child.
if(node.right==null){
BinaryNode newNode=new BinaryNode(element);
node.right=newNode;
size++;
return true;
}
else{
return insert(element,node.right);
}
}
}
二叉查找树的查找算法:
1.若b是空树,则搜索失败,否则:
2.若x等于b的根节点的数据值,则查找成功,否则:
3.若x小于b的根节点的数据值,则搜索左子树,否则:
4.搜索右子树。
相关代码如下:
//Search in the whole tree
public boolean contains(AnyType element){
return contains(element, root);
}
//Search it recursively!
private boolean contains(AnyType element, BinaryNode node){
if(node==null) return false;
if(element.compareTo(node.data)<0) return contains(element, node.left);
else if(element.compareTo(node.data)>0) return contains(element, node.right);
else return true;
}
//This is the external method to find the minimum value.
//The data value will be returned! Not the node.
public AnyType findMin(){
return findMin(root).data;
}
//This the internal method to find the minimum NODE recursively.
//The node with the minimum value will be returned! Not the value!
private BinaryNode findMin(BinaryNode node){
if(node==null) return null;
else if(node.left!=null) return findMin(node.left);
else return node;
}
public AnyType findMax(){
return findMax(root).data;
}
//This is the internal method to find the maximum NODE.
//But it's done with a while loop instead of recursion.
//The node with the maximum value will be returned! Not the value!
private BinaryNode findMax(BinaryNode node){
if(node!=null)
while(node.right!=null)
node=node.right;
return node;
}
在二叉查找树中删去一个节点,分三种情况讨论:
1.若P节点为叶子节点,即PL和PR均为空树,则直接删除该节点即可(修改它的父节点即可)。
2.若P节点只有左子树PL或右子树PR,此时只要修改P的父节点的相关数据域,将其直接连接到PL或PR即可,该修改不会破坏二叉排序树的特性。
3.若P节点的左子树和右子树均不为空,此时的做法是,找到P节点的右子树中的最小值,将该值取代P,然后对该右子树中最小值所在的节点进行删除操作。
相关代码如下:
public AnyType findMin(){
return findMin(root).data;
}
//This the internal method to find the minimum NODE recursively.
//The node with the minimum value will be returned! Not the value!
private BinaryNode findMin(BinaryNode node){
if(node==null) return null;
else if(node.left!=null) return findMin(node.left);
else return node;
}
public AnyType findMax(){
return findMax(root).data;
}
//This is the internal method to find the maximum NODE.
//But it's done with a while loop instead of recursion.
//The node with the maximum value will be returned! Not the value!
private BinaryNode findMax(BinaryNode node){
if(node!=null)
while(node.right!=null)
node=node.right;
return node;
}
相当简单,直接给出代码,调整三行语句的顺序可以改变为前序遍历与后序遍历,实现层次遍历需要队列。主语 !=null 条件:
public void printTree(){
if(isEmpty()){
System.out.println("The tree is empty!");
}
else{
printTree(root);
}
}
//This is the internal method which will implements inorder traversal.
//Change the order of statements can change it into a preorder/postorder traversal.
//To have a level order traversal will use a queue.
private void printTree(BinaryNode node){
if(node!=null){
printTree(node.left);
System.out.println(node.data);
printTree(node.right);
}
}