数据结构之二叉排序树
二叉排序树:或者是一颗空树;或者是具有下列性质的二叉树:1)若他的左子树不空,则左子树上所有结点的值均小于它的根节点的值;2)若他的右子树不为空,则右子树上所有节点的值均大于它的根节点的值;3)他的左右子树也分别为二叉排序树。
二叉排序树的创建以及增删改查
package treelearning;
import java.util.Scanner;
public class BiSearchTree {
private TreeNode root;//定义根节点属性便于操作
public TreeNode getRoot() {
return root;
}
public void setRoot(TreeNode root) {
this.root = root;
}
//创建一颗二叉排序树,实质上就是一颗空树的依次插入。
public void creatBST(int[] datas)
{
//按输入顺序依次插入节点
for(int i=0;i<datas.length;i++)
{
this.InsertBST(datas[i]);
}
}
//查找二叉树的节点,给外部的方法
public void searchBST(int target)
{
if(root==null)
System.out.println("该树为空树");
else this.searchBST(root, target,null);
}
/*
* @param:tempNode,指向当前节点;preNode,当前节点的双亲节点;target,目标所需要查找的值。
* 实际的迭代查找,查找成功返回当前节节点,即目标节点;查找失败则返回查找路径上的最后一个节点,即插入该元素的双亲节点。
*/
private TreeNode searchBST(TreeNode tempNode,int target,TreeNode preNode)
{
if(tempNode==null) {tempNode=preNode; return tempNode; }
else if(target==tempNode.getThreshold()) return tempNode;
else if(target<tempNode.getThreshold()) return this.searchBST(tempNode.getLeftchild(), target,tempNode);
else return this.searchBST(tempNode.getRightchild(), target,tempNode);
}
/*
* 因为查找失败反回了该节点插入的双亲节点的位置,只需判断应该插入在双亲节点的哪个节点即可。
*/
public void InsertBST(int target)
{
TreeNode targetNode=this.searchBST(root, target,null);
if(targetNode==null)
{
//System.out.print(target+" ");
targetNode=new TreeNode();
targetNode.setThreshold(target);
this.setRoot(targetNode);
}
else if(target<targetNode.getThreshold()) {
TreeNode insertNode=new TreeNode();
insertNode.setThreshold(target);
targetNode.setLeftchild(insertNode);
}
else if(target>targetNode.getThreshold()) {
TreeNode insertNode=new TreeNode();
insertNode.setThreshold(target);
targetNode.setRightchild(insertNode);
}
else System.out.println("您要插入的节点已经存在");
}
public void deleteBST(int target)
{
TreeNode targetNode=this.deleteBST(root, target);
//System.out.println(targetNode.getThreshold());
this.searchPreNode(targetNode, this.getRoot(),this.getRoot());
//System.out.println(preNode.getThreshold());
if(targetNode==null) System.out.println("您要删除的节点不存在");
//删除的节点为叶子节点
else if(targetNode.getLeftchild()==null&&targetNode.getRightchild()==null)
{
if(parentNode.getLeftchild().equals(targetNode)) parentNode.setLeftchild(null);
else parentNode.setRightchild(null);
}
//删除的节点左节点为空,只需把双亲节指向该节点的指针换成该节点的右节点即可。
else if(targetNode.getLeftchild()==null)
{
if(parentNode.getLeftchild().equals(targetNode)) parentNode.setLeftchild(targetNode.getRightchild());
else parentNode.setRightchild(targetNode.getRightchild());
}
//删除的节点右节点为空,只需把双亲节指向该节点的指针换成该节点的左节点即可。
else if(targetNode.getRightchild()==null)
{
if(parentNode.getLeftchild().equals(targetNode)) parentNode.setLeftchild(targetNode.getLeftchild());
else parentNode.setRightchild(targetNode.getLeftchild());
}
//删除节点的左右节点都不为空,找到删除节点的直接前驱节点;直接前驱节点的双亲节点右节点指向该前驱结点的左子树。把删除节点替换称直接前驱节点即可。
else {
TreeNode preNode=targetNode;TreeNode tempNode=targetNode.getLeftchild();
while(tempNode.getRightchild()!=null) {preNode=tempNode; tempNode=tempNode.getRightchild();}
//System.out.println("前继节点为"+tempNode.getThreshold()+",前继节点的双亲为"+preNode.getThreshold()+",删除节点的双亲为"+parentNode.getThreshold());
targetNode.setThreshold(tempNode.getThreshold());
if(!preNode.equals(targetNode)) preNode.setRightchild(tempNode.getLeftchild());
else preNode.setLeftchild(tempNode.getLeftchild());
tempNode.setLeftchild(null);//等待jvm自动回收
}
parentNode=null;//全局变量用完后初始化。
}
private static TreeNode parentNode=null;//记录要删除节点的双亲节点
/*
* 找到删除节点的双亲节点
*/
public void searchPreNode(TreeNode target,TreeNode tempNode,TreeNode preNode)
{
if(tempNode!=null)
{
if(tempNode.equals(target)) parentNode=preNode;
else {
this.searchPreNode(target, tempNode.getLeftchild(), tempNode);
this.searchPreNode(target, tempNode.getRightchild(), tempNode);
}
}
}
/*
* 找到删除节点并返回该节点。
*/
public TreeNode deleteBST(TreeNode tempNode,int target)
{
if(tempNode==null) return null;
else if(tempNode.getThreshold()==target) return tempNode;
else if(target<tempNode.getThreshold()) return this.deleteBST(tempNode.getLeftchild(), target);
else return this.deleteBST(tempNode.getRightchild(), target);
}
/*
* 中序遍历
*/
public void inOrderVisitBST()
{
this.inOrderVisitBST(root);
System.out.println();
}
private void inOrderVisitBST(TreeNode tempNode)
{
if(tempNode!=null)
{
//System.out.println("111");
this.inOrderVisitBST(tempNode.getLeftchild());
System.out.print(tempNode.getThreshold()+" ");
this.inOrderVisitBST(tempNode.getRightchild());
}
}
public static void main(String[] args)
{
Scanner in =new Scanner(System.in);
int[] initdatas=new int[] {45,12,53,3,37,100,9,24,61,6};
/*for(int i=0;i<initdatas.length;i++)
{
initdatas[i]=in.nextInt();
}*/
BiSearchTree bst=new BiSearchTree();
bst.creatBST(initdatas);
/* boolean test=bst.getRoot()==null?false:true;
if(test) System.out.println("111");*/
bst.inOrderVisitBST();
bst.deleteBST(45);
bst.inOrderVisitBST();
}
}
菜鸟学习中,请大佬指教;别喷的太狠,给点面子谢谢。