首页 > 代码库 > 二叉查找树BST----java实现
二叉查找树BST----java实现
二叉查找树BST----java实现
1.二叉查找树简介
二叉查找树又名二叉搜索树和二叉排序树。性质如下:
在二叉查找树中:
(01) 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(02) 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(03) 任意节点的左、右子树也分别为二叉查找树。
(04) 没有键值相等的节点(no duplicate nodes)。
2.二叉查找树节点类
class TreeNode { int value; TreeNode parent; TreeNode left; TreeNode right; public TreeNode(int value, TreeNode parent, TreeNode left, TreeNode right) { this.value = http://www.mamicode.com/value;>3.遍历
二叉查找树的遍历同二叉树的遍历,递归与非递归方法详见《二叉树的递归遍历和非递归遍历(附详细例子)》
4.最大和最小值
a.BST中的最小值即最左的孩子。
//求BST的最小值 public TreeNode getMin(TreeNode root) { if(root==null) return null; while(root.left!=null) root=root.left; return root; }b.BST中的最大值即最右的孩子。
//求BST的最大值 public TreeNode getMax(TreeNode root) { if(root==null) return null; while(root.right!=null) root=root.right; return root; }5.前驱和后继节点
ps:图片来于网络
a.BST中某节点前驱节点==小于该节点的所有节点中的最大值
前驱容易情形:5寻前驱 4
前驱复杂情形:11寻前驱 10
//查找BST中某节点的前驱节点.即查找数据值小于该结点的最大结点。 public TreeNode preNode(TreeNode x) { if(x==null) return null; // 如果x存在左孩子,则"x的前驱结点"为 "以其左孩子为根的子树的最大结点"。 if(x.left!=null) return getMax(x.left); // 如果x没有左孩子。则x有以下两种可能: // (01) x是"一个右孩子",则"x的前驱结点"为 "它的父结点"。 // (02) x是"一个左孩子",则 前驱节点为x的某一个祖先节点的父节点,而且该祖先节点是作为其父节点的右儿子 TreeNode p=x.parent; while(p!=null&&p.left==x) { x=p;//父节点置为新的x p=p.parent; //父节点的父节点置为新的父节点 } return p; }b.BST中某节点后继节点==大于该节点的所有节点中的最小值后继容易情形:5寻后继 6
复杂情形:9寻后继 10
//查找BST中某节点的后继节点.即查找数据值大于该结点的最小结点。 public TreeNode postNode(TreeNode x) { if(x==null) return null; // 如果x存在右孩子,则"x的后继结点"为 "以其右孩子为根的子树的最小结点"。 if(x.left!=null) return getMin(x.right); // 如果x没有右孩子。则x有以下两种可能: // (01) x是"一个左孩子",则"x的后继结点"为 "它的父结点"。 // (02) x是"一个右孩子",则 前驱节点为x的某一个祖先节点的父节点,而且该祖先节点是作为其父节点的左儿子 TreeNode p=x.parent; while(p!=null&&p.right==x) { x=p;//父节点置为新的x p=p.parent; //父节点的父节点置为新的父节点 } return p; }6.查找
查找值为val的节点,如果小于根节点在左子树查找,反之在右子树查找
//查找值为val的节点 --递归版-- public TreeNode searchRec(TreeNode root ,int val) { if(root==null) return root; if(val<root.value) return searchRec(root.left,val); else if(val>root.value) return searchRec(root.right,val); else return root; } //查找值为val的节点 --非 递归版-- public TreeNode search(TreeNode root ,int val) { if(root==null) return root; while(root!=null) { if(val<root.value) root=root.left; else if(val>root.value) root=root.right; else return root; } return root; }7.插入
a.若当前的二叉查找树为空,则插入的元素为根节点
b.若插入的元素值小于根节点值,则将元素插入到左子树中
c.若插入的元素值不小于根节点值,则将元素插入到右子树中。首先找到插入的位置,要么向左,要么向右,直到找到空结点,即为插入位置,如果找到了相同值的结点,插入失败。
//BST插入节点 --递归版-- public TreeNode insertRec(TreeNode root,TreeNode x) { if(root==null) root=x; else if(x.value<root.value) root.left=insertRec(root.left, x); else if(x.value>root.value) root.right=insertRec(root.right, x); return root; } //BST插入节点 --非 递归版-- public TreeNode insert(TreeNode root,TreeNode x) { if(root==null) root=x; TreeNode p=null;//需要记录父节点 while(root!=null)//定位插入的位置 { p=root;//记录父节点 if(x.value<root.value) root=root.left; else root=root.right; } x.parent=p;//定位到合适的页节点的空白处后,根据和父节点的大小比较插入合适的位置 if(x.value<p.value) p.left=x; else if(x.value>p.value) p.right=x; return root; }8.删除
二叉查找树的删除,分三种情况进行处理:
1.p为叶子节点,直接删除该节点,再修改其父节点的指针(注意分是根节点和不是根节点),如图a。
2.p为单支节点(即只有左子树或右子树)。让p的子树与p的父亲节点相连,删除p即可;(注意分是根节点和不是根节点);如图b。
3.有两个孩子的情况,当前结点与左子树中最大的元素交换,然后删除当前结点。左子树最大的元素一定是叶子结点,交换后,当前结点即为叶子结点,删除参考没有孩子的情况。另一种方法是,当前结点与右子树中最小的元素交换,然后删除当前结点。如图c。
ps:图片来于网络