【数据结构】二叉搜索树

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/LoveHYZH/article/details/79078803

1.BinarySearchTree的性质

  • 一个节点的左子树只能包含键值小于该节点键值的节点
  • 一个节点的右子树只能包含键值大于该节点键值的节点
  • 左子树和右子树必须也是BST
  • 按照中序遍历得到的是从小到大排列的序列

2.为什么用BST

  • 对节点的数据进行一定的约束,使得最坏情况下平均搜索的时间复杂度降低至 O(log2n)

3.二叉搜索树的结构

public class BST{
    private static class BSTNode{
        public int data;
        public BSTNode left;
        public BSTNode right;
        public BSTNode(int data, BSTNode left, BSTNode right){
            this.data = data;
            this.left = left;
            this.right = right;
        }
    }
    private BSTNode root;
}

4.在以p为根节点二叉搜索树中查找元素

//查找元素(递归)
public BSTNode search(BSTNode p, int data){
    if(p == null){
        return null;
    }
    if(data < p.getData()){
        return search(p.left, data);
    }
    if(data > p.getData()){
        return search(p.right, data);
    }
    return p; //等于时,即找到该节点,直接返回
}

//查找元素(非递归)
public BSTNode search(BSTNode p, int data){
    while(p != null){
        if(data == p.getData()){
            return p;
        }
        if(data < p.getData()){
            p = p.left;
        }
        if(data > p.getData()){
            p = p.right;
        }
    }
    return null;
}

5.在以p为根节点的二叉搜索树中寻找最小元素

public BSTNode min(BSTNode p){
    if( p == null){
        return null;
    }
    while(p.left != null){
        p = p.left;
    }
    return p;
}

6.在以p为根节点的二叉搜索树中寻找最大元素

public BSTNode max(BSTNode p){
    if( p == null){
        return null;
    }
    while(p.right != null){
        p = p.right;
    }
    return p;
}

7.在以p为根节点的二叉搜索树中插入元素

//与查找元素逻辑体类似
public BSTNode insert(BSTNode p, int data){
    if(p == null){
        p = new BSTNode(data, null, null);
        return p;
    }
    if(data < p.getData()){
        p.left = insert(p.left, data);
    }
    if(data > p.getData()){
        p.right = insert(p.right, data);
    }
    return p; //插入元素在二叉排序树中存在时,不处理,返回该元素
}

8.在以p为根节点的二叉搜索树中删除元素

/**
 * ①删除的是叶子节点
 *  此时和②合并同样处理
 *  
 * ②删除的是有一个孩子的节点
 *  让该节点双亲直接指向孩子节点
 *  
 * ③删除的是有两个孩子的节点
 *  将其左子树最大值赋值给这个节点(或者右子树最小值)
 *  递归直到只有一个孩子节点按②操作
 *  
 *  @param p 想要执行删除操作的树的根节点
 *  @param data 想要删除的节点的元素值
 *  @return 二叉排序树p执行删除后的根节点p
 */
public BSTNode remove(BSTNode p, int data){
    BSTNode temp;
    if(p == null){
        throw new NoSuchElementException("the element is not exist");
    }else if(data < p.getData()){
        p.left = remove(p.left, data); //类似这种递归方式,避免了没有指向双亲节点指针的尴尬
    }else if(data > p.getData()){
        p.right = remove(p.right, data);
    }else{      /*找到该节点*/
        //2个孩子节点
        if(p.left != null && p.right != null){
            temp = max(p.left);
            p.setData(temp.getData());
            p.left = remove(p.left, p.getData());
        }else{         
            //1个孩子节点
            if(p.left == null){
                p = p.right;
            }else{      /*此处包括叶子节点情况*/
                p = p.left;
            }
        }
    }
    return p;
}

9.平衡二叉搜索树

  • 高度平衡树:用 HB(k) 表示,k为左右子树高度差,k是平衡因子
  • 完全平衡二叉搜索树: HB(0) ,此时保证树为完全二叉树

猜你喜欢

转载自blog.csdn.net/LoveHYZH/article/details/79078803