BST树二叉搜索树
左子树比根节点小,右子树比根节点大
BST树节点
public class BSTNode {
int data;
BSTNode left;
BSTNode right;
public BSTNode(int data, BSTNode left, BSTNode right) {
this.data = data;
this.left = left;
this.right = right;
}
}
BST树常见操作:
public class BinarySearchTree {
//BST树的根节点的引用
public BSTNode root;
public BinarySearchTree() {
this.root = null;
}
/**
* 非递归实现BST树的插入操作
* @param val
*/
public void insert_non(int val){
//1.考虑根节点的特殊情况
if(root == null){
root = new BSTNode(val, null, null);
return;
}
//2.寻找val值需要插入的地方
BSTNode parent = null;
BSTNode cur = root;
while(cur != null){
if(val < cur.data){
parent = cur;
cur = cur.left;
} else if(val > cur.data){
parent = cur;
cur = cur.right;
} else {
return;
}
}
//3.把val值生成新节点插入到BST树当中
if(val < parent.data){
parent.left = new BSTNode(val, null, null);
} else {
parent.right = new BSTNode(val, null, null);
}
}
/**
* 递归实现BST树的插入操作
* @param val
*/
public void insert(int val){
root = insert(root, val);
}
/**
* 从root节点开始寻找位置,插入val
* @param root
* @param val
* @return
*/
private BSTNode insert(BSTNode root, int val) {
if(root == null){
return new BSTNode(val, null, null);
}
if(val < root.data){
root.left = insert(root.left, val);
} else if(val > root.data){
root.right = insert(root.right, val);
}
return root;
}
/**
* 非递归实现BST的删除操作
* 1.有两个孩子 用前驱或者后继节点代替一下
* 2.有一个孩子
* 3.叶子节点
* @param val
*/
public void remove_non(int val){
//1.找到值为val的节点
BSTNode parent = null;
BSTNode cur = root;
while(cur != null){
if(val < cur.data){
parent = cur;
cur = cur.left;
} else if(val > cur.data){
parent = cur;
cur = cur.right;
} else {
break;
}
}
//要删除的结点不存在
if(cur == null){
return;
}
//2.处理有两个孩子的节点
if(cur.left != null && cur.right != null){
parent = cur;
//用前驱节点来代替(左孩子的最后一个右子树结点)
/*BSTNode p = cur.left;
while(p.right != null){
parent = p;
p = p.right;
}*/
//用后继节点来代替 (右孩子的最后一个左子树结点)
BSTNode p = cur.right;
while(p.left != null){
parent = p;
p = p.left;
}
cur.data = p.data;
cur = p;
}
//3.删除cur引用的节点 处理2,3的情况
BSTNode child = cur.left;
if(child == null){
child = cur.right;
}
if(parent==null){ //删除根结点 根节点只有一个孩子
root=child;
} else if(cur.data < parent.data){ // cur在parent左孩子上
parent.left = child;
} else {
parent.right = child;
}
}
/**
* 用递归删除BST树中值为val的节点
* @param val
*/
public void remove(int val){
root = remove(root, val);
}
/**
* 递归删除值为val的节点,删除以后,把根节点返回回去
* @param root
* @param val
* @return
*/
private BSTNode remove(BSTNode root, int val) {
if(root == null){
return null;
}
if(val < root.data){
root.left = remove(root.left, val);
} else if(val > root.data){
root.right = remove(root.right, val);
} else {
//表示找到值为val的节点了
if(root.left != null && root.right != null){
//后继节点替换
BSTNode p = root.right;
while(p.left != null){
p = p.left;
}
root.data = p.data;
root.right = remove(root.right, p.data);
} else {
//有一个孩子或者叶子节点
if(root.left != null){
return root.left;
}
if(root.right != null) {
return root.right;
}
return null;
}
}
return root;
}
/**
* BST树的搜索,找值为val的节点是否存在
* @param val
* @return
*/
public boolean query1(BSTNode root,int val){
boolean res=false;
if(root==null) {
return false;
}else if(root.data==val){
return true;
}else{
res=query1(root.left,val);
if(res==false){
res=query1(root.right,val);
}
return res;
}
}
/**
* BST树的搜索,找值为val的节点是否存在 返回结点
* @param val
* @return
*/
public BSTNode query(int val){
return query(root, val);
}
/**
* 递归搜索值为val的节点
* @param root
* @param val
* @return
*/
private BSTNode query(BSTNode root, int val) {
if(root == null){
return null;
}
if(val < root.data){
return query(root.left, val);
} else if(val > root.data){
return query(root.right, val);
} else{
return root;
}
}
/**
* BST的前序遍历递归 VLR
*/
public void preOrder(BSTNode root){
if(root==null) return;
System.out.print(root.data +" ");
preOrder(root.left);
preOrder(root.right);
}
/**
* 非递归前序遍历(栈来实现) 根节点入栈(从根结点开始的左子树的左孩子一直入栈直到NULL ),且在入栈之前打印结点的data,
* 出栈,root指向栈顶元素(当前结点)的右孩子 右孩子不为null 时 打印 并入栈 ;右孩子为NULL 继续出栈下一个元素;
*
* @param root
*/
public void NicePreOrder(BSTNode root){
if(root==null){
return;
}
Stack<BSTNode> st=new Stack<BSTNode>();
while(!st.isEmpty() || root!=null) {
while (root != null) {
System.out.print(root.data + " ");
st.push(root);
root = root.left;
}
if (!st.isEmpty()) {
root = st.peek();
st.pop();
root = root.right;
}
}
}
/**
* BST的中序遍历递归 LVR
*/
public void inOrder(BSTNode root){
if(root==null){
return;
}
inOrder(root.left);
System.out.print(root.data +" ");
inOrder(root.right);
}
/**
* 非递归中序遍历
* 从根节点开始到左孩子的left一直入栈
*
* 出栈,并打印 ,如果当前出栈元素的右孩子不为NULL(以及右孩子的左子树不为NULL)就全部入栈,如果为null 继续出栈下一个元素;
* @param root
*/
public void NiceInOder(BSTNode root){
if(root==null){
return;
}
Stack<BSTNode> st=new Stack<BSTNode>();
while(!st.isEmpty() || root!=null) {
while (root != null) {
st.push(root);
root = root.left;
}
root = st.peek();
st.pop();
System.out.print(root.data + " ");
root = root.right; //右孩子以及右孩子的左子树都入栈;
}
}
/**
* BST树的后序遍历 LRV 对每课树都是LRV
*/
public void lastOrder(BSTNode root){
if(root==null){
return;
}
lastOrder(root.left);
lastOrder(root.right);
System.out.print(root.data +" ");
}
/**
* 非递归后序
*
* 从根节点开始往left一直入栈
* 出栈之前先判断当前栈顶元素的右孩子以及右孩子的左子树是否为NULL 不为null时先入栈
* 为NULL时,就出栈并 打印栈顶元素
* @param root
*
*/
//LRV 出栈之前先把右孩子以及右孩子的左子树都入栈
public void NiceLastOrder(BSTNode root){
if(root==null){
return;
}
Stack<BSTNode> st=new Stack<BSTNode>();
BSTNode tag=null;
while (!st.isEmpty() || root!=null){
while(root!=null){
st.push(root);
root=root.left;
}
root=st.peek();
st.pop();
if(root.right==null || root.right==tag){ //找栈顶值的右孩子
System.out.print(root.data+" ");
tag=root;
root=null;
}else{ //有右孩子
st.push(root);
root=root.right;
}
}
}
/**
* 层序遍历 出队打印后把左右孩子都入队
*/
public void levelOrder(BSTNode root){
if(root==null){
return;
}
Queue<BSTNode> qu=new LinkedList<BSTNode>();
qu.add(root);
while (!qu.isEmpty()){
root=qu.peek(); //从对头获取元素
qu.poll(); //从队中移出
System.out.print(root.data+" ");
if(root.left!=null){
qu.add(root.left);
}
if(root.right!=null){
qu.add(root.right);
}
}
}
/**
*
* @param root
*/
public void LeveOrder(BSTNode root){
int height=height(root);
for(int i=0;i<=height;i++){
leve(root,i);
}
System.out.println();
}
private void leve(BSTNode root, int i) {
if(root==null){ //BST不一定是一颗完全树
return;
}
if(i==1) {
System.out.print(root.data +" ");
}
leve(root.left,i-1);
leve(root.right,i-1);
}
/**
* 递归实现求BST树的高度/层数
* @return
*/
public int height(BSTNode root){
if(root==null){
return 0;
}
return height(root.left)>height(root.right)?height(root.left)+1:height(root.right)+1;
}
/**
* 递归实现求BST树节点的个数
* @return
*/
public int number(BSTNode root){
if(root==null){
return 0;
}
return number(root.right)+number(root.left)+1;
}
/**
* 求二叉树满足某一个区间[begin, end]的所有节点的值,放入list当中
*/
public List<Integer> findAreaValue(int begin, int end){
List<Integer> list=new ArrayList<Integer>();
findValue(root,list,begin,end);
return list;
}
private void findValue(BSTNode root, List<Integer> list, int begin, int end) {
if(root!=null){
findValue(root.left,list,begin,end);
if(root.data>begin && root.data<end){
list.add(root.data);
}else if(root.data>end){
return;
}
findValue(root.right,list,begin,end);
}
}
/**
* 求BST的镜像 交换每一颗子树的左右孩子
*/
public void mirror(BSTNode root){
if(root == null){
return;
}
Stack<BSTNode> stack = new Stack<BSTNode>();
stack.push(root);
while(!stack.isEmpty()){
BSTNode node = stack.pop();
if(node.left != null||node.right != null){
BSTNode temp = node.left;
node.left = node.right;
node.right = temp;
}
if(node.left!=null){
stack.push(node.left);
}
if(node.right!=null){
stack.push(node.right);
}
}
}
/**
* 递归求镜像
* @param root
*/
public void mirror1(BSTNode root){
if(root==null){
return;
}
BSTNode temp =root.left;
root.left = root.right;
root.right = temp;
mirror1(root.left);
mirror1(root.right);
}
/**
* 判断形参bst树,是不是当前BST树(this)的一颗子树结构
* @param bst
* @return
*/
public boolean isChildTree(BinarySearchTree bst){
boolean res=false;
//当Tree1和Tree2都不为null的时候才可以比较
if(this!=null && bst!=null) {
//如果找到了对应的Tree2的根节点的点
if (this.root.data == bst.root.data) {
res=HaveTree(this.root,bst.root);
//如果未找到,则以根节点的左孩子为起点,去判断是否包含Tree2
if(!res){
res=HaveTree(this.root.left,bst.root);
}
//如果未找到,则以根节点的右孩子为起点,去判断是否包含Tree2
if(!res){
res=HaveTree(this.root.right,bst.root);
}
}
}
return res;
}
private boolean HaveTree(BSTNode root1, BSTNode root2) {
//root2遍历完了 全部匹配
if(root2==null){
return true;
}else if(root1==null){ //root1先遍历完了 root2中存在在root1没有的结点;
return false;
}
if(root1==null && root2==null){ //两棵树的结点一直相等,直到结点遍历完了
return true;
}
if(root1.data!=root2.data){
return false;
}
//如果根节点对应的上,那么就分别去子节点里面匹配
return HaveTree(root1.left, root2.left)&& HaveTree(root1.right, root2.right);
}
/**
* 从root节点开始,求val1和val2的最近公共祖先节点,并返回该祖先节点的值val LCA
* @param val1
* @param val2
* @return
*/
public int getLCA1(int val1, int val2){
BSTNode node1 = query(val1);
BSTNode node2 = query(val2);
return getLCA(root, node1, node2);
}
/**
*
* @param root
* @param node1
* @param node2
* @return
*/
private int getLCA(BSTNode root, BSTNode node1, BSTNode node2) {
if(node1.data < root.data && node2.data < root.data){
return getLCA(root.left, node1, node2);
} else if(node1.data > root.data && node2.data > root.data){
return getLCA(root.right, node1, node2);
} else {
return root.data;
}
}
/**
* 从root节点开始,求val1和val2的最近公共祖先节点,并返回该祖先节点的值val LCA
* @param val1
* @param val2
* @return
*/
public int getLCA(int val1, int val2){
if(root==null){
return -1;
}
while(root!=null){
if(root.data>val1 && root.data>val2){
root=root.left;
}else if(root.data<val1 && root.data<val2){
root=root.right;
}else {
return root.data;
}
}
return -1;
}
/**
* 寻找中序遍历第K个节点
* @param k
* @return
*/
public int getInOrderNoK(BSTNode root,int k){
int count=0;
Stack<BSTNode> st=new Stack<BSTNode>();
if(count>k || root==null){
return -1;
}
while(!st.isEmpty()|| root!=null) {
while (root != null) {
st.push(root);
root = root.left;
}
root = st.peek();
count++;
if (count == k) {
return root.data;
}
st.pop();
root = root.right;
}
return -1;
}
}