二叉查找树在数据结构中也经常会被用到。所谓二叉查找树就是从根节点开始,左边的节点比右边的节点小。显然BST的前序遍历就是一个从小到大的有序数组。
JAVA构建二叉查找树:
// 构建一颗二叉查找树
/*原理:
* 下一个数据和根节点比较,比根大放在根的右边,然后再跟节点的右孩子节点比较
* 比根节点小,则放在根节点的左侧,
* 如果等于根,那么不操作
* 注意:容易出现两种极端情形,该树全是左节点,或者全是右节点,那么平均查找时间依然是o(n),
* 这两种情形都不是我们想要看到的,因为BST的目的就是为了提高搜索效率
*/
public static TreeNode<Integer> getBSTree(int[]obj)
{
TreeNode<Integer>root =null;
for (int i = 0; i < obj.length; i++)
{
root=insertBSTNode(root, obj[i]);
}
return root;
}
//向BST中插入一个节点
public static TreeNode<Integer> insertBSTNode(TreeNode<Integer>root,int data)
{
if(root==null)
return new TreeNode<Integer>(data);
// TreeNode<Integer> tempNode=root;
if(root.data<data)//大于节点值,插在节点右边
{
root.rightNode=insertBSTNode(root.rightNode, data);
}
else if(root.data>data)//小于节点值,插在节点左边
{
root.leftNode=insertBSTNode(root.leftNode, data);
}
return root;
}
//根据值查找BST中相应的节点
public static TreeNode<Integer>findBSTNode(TreeNode<Integer>root,int data)
{
/*//递归实现
if(root==null)
return null;
if(root.data==data)
return root;
else if(root.data>data)//查找左边的
return findBSTNode(root.leftNode, data);
else//查找右边的
return findBSTNode(root.rightNode, data);
*/
//非递归实现
TreeNode<Integer>tempNode=root;
while(tempNode!=null)
{
if(tempNode.data==data)
return tempNode;
else if(tempNode.data<data)
tempNode=tempNode.rightNode;
else
tempNode=tempNode.leftNode;
}
return null;
}
//查找BST树中最大值,即最右边的节点
public static int findBSTNodeMax(TreeNode<Integer>root)
{
/*递归实现
if(root==null)//不存在
return -1;
if(root.rightNode==null)
return root.data;
else
return findBSTNodeMax(root.rightNode, data);
*/
//非递归实现
TreeNode<Integer>tempNode=root;
if(tempNode!=null)
while(tempNode.rightNode!=null)
{
tempNode=tempNode.rightNode;
}
return tempNode.data;
}
//查找BST树中最小值,即最左边的节点
public static TreeNode<Integer> findBSTNodeMin(TreeNode<Integer>root)
{
/*递归实现
if(root==null)//不存在
return -1;
if(root.leftNode==null)
return root.data;
else
return findBSTNodeMin(root.leftNode, data);
*/
//非递归实现
TreeNode<Integer>tempNode=root;
if(tempNode!=null)
while(tempNode.leftNode!=null)
{
tempNode=tempNode.leftNode;
}
return tempNode;
}
//向BST树中删除一个数据
//有三种情况情况,
//1.该节点没有子节点直接删除
//2.该节点只有一个节点,那么直接将他的父节点和子节点相连
//3.该节点有两个节点,那么找到他的最小的孩子节点来替换要该删除的节点,然后删除最小的孩子节点
//PS:该最小的孩子节点最多只有一个孩子节点
public static void deleteBSTNode(TreeNode<Integer>root,int data)
{
if(root==null)
;
if(root.data>data)//删除左边
deleteBSTNode(root.leftNode, data);
else if(root.data<data)//删除右边
deleteBSTNode(root.rightNode, data);
else //开始删除了
{
//情形1,没有节点直接删除
if(root.leftNode==null&&root.rightNode==null)
root=null;
//情形3
else if(root.rightNode!=null&&root.leftNode!=null)
{
TreeNode<Integer>tempNode=findBSTNodeMin(root);//找到最左边的节点
deleteBSTNode(root, tempNode.data);
root.data=tempNode.data;
}
//情形2
else
root=root.leftNode==null?root.rightNode:root.leftNode;
}
}