二叉搜索树(BST)

二叉树:每个节点最多有两个孩子,是一种动态数据结构,具有递归结构。

//二叉树的节点定义
class Node> {
    E e;
    Node left;
    Node right;
    
    public Node(e) {
        this.e = e;
        left = null;
        right = null;
    }
    
    public String toString() {
        return e.toString();
    }
}

其中空树和只有根节点的树都是二叉树。

满二叉树:对于每一个非叶子节点都有两个节点。

  1. 二分搜索数(BST)

    • 对于每一个节点的值,都大于其左子树的所有节点,小于其右子树的所有节点。另外存储的元素是可比较的。

      public class BST> {
          
          private Node root;  //BST的根节点
          private int size;   //BST的大小
          
          public BST() {
              root = null;
              size = 0;
          }
          
      }
      

    BST的一些重要操作

    • contains(E e):判断元素e是否在该BST中

      public boolean contains(E e) {
          return contains(root, e);
      }
      //在以node为根的BST中,判断元素e是否存在于BST中
      private boolean contains(Node node, E e) {
          if(node == null) {
              //没找到e元素
              return false;
          }
          if(e.compareTo(node.e) < 0) {
              //去左子树
              return contains(node.left, e);
          }else if(e.compareTo(node.e) > 0) {
              //去右子树
              return contains(node.right, e);
          }else{
              //找到了e
              return true;
          }
      }
      
    • add(E e):向BST中添加元素e

      public void add(E e) {
          if(root == null) {
              //空树
              root = new Node(e);
              size ++
          }else{
              add(root, e);
          }
          
      }
      
      //在以node为根的BST中添加一个元素,并返回操作之后的以node为根节点的BST
      private Node add(Node node, E e) {
          if(node == null) {
              //找待插入的位置
              size ++;
              //生成新结点,并向上层返回,与上层链接
              return new Node(e);
          }
          if(e.compareTo(node.e) < 0) {
              //去往左子树,并接受返回的树
              node.left = add(node.left, e);
          }else if(e.compareTo(node.e) > 0) {
              //去往右子树,并接受返回的树
              node.right = add(node.right, e)
          }
          return node;
      }
      
    • getMin():获取BST中的最小值节点的值

      public E getMin() {
          if(isEmpty()) {
              throw new RuntimeException("Empty BST!");
          }
          return getMin(root).e;
      }
      
      private Node getMin(Node node) {
          if(node.left == null) {
              return node;
          }
          return getMin(node.left);
      }
      
    • getMax():获取BST中最大节点的值

      public E getMax() {
          if(isEmpty()) {
              throw new RuntimeException("Empty BST!");
          }
          return getMax(root).e;
      }
      
      private Node getMax(Node node) {
          if(node.right == null) {
              return node;
          }
          return getMax(node.right);
      }
      
      
    • remove():移除操作

      public void remove(E e) {
          //注意:root仍然需要承接删除节点后的树
          root = remove(root, e);
      }
      
      public E removeMin() {
          root = remove(root);
          return getMin();
      }
      
      //在以node为根的BST中,删除元素e,返回删除之后的新树
      private Node removeMin(Node node) {
          if(node.left == null) {
              Node rightNode = node.right;
              node.right = null;
              size --;
              return rightNode;
          }
          node.left = removeMin(node.left);
          return node;
      }
      
      private Node remove(Node node, E e) {
          if(node == null) {
              return null;
          }
          if(e.compareTo(node.e) < 0) {
              node.left = remove(node.left, e);
              return node;
          }else if(e.compareTo(node.e) > 0){
              node.right = remove(node.right, e);
              return node;
          }else{
              if(node.right == null) {
                  //没有右子树的情况
                  Node leftNode = node.left;
                  node.left = null;
                  size --;
                  return leftNode;
              }
              if(node.left == null) {
                  //没有左子树的情况
                  Node rightNode = node.right;
                  node.right = null;
                  size --;
                  return rightNode;
              }
              //左右子树均存在
              //获取待删除节点的右子树的最小节点
              Node successor = getMin(node.right);
              //后继结点的右子树接替删除右子树中最小节点后的新树
              successor.right = removeMin(node.right);
              successor.left = node.left;
              
              node.left = node.right = null;
          }
          
      }
      
    • 遍历BST

      • 先序遍历

        //递归写法
        public void preOrder() {
            preOrder(root);
        }
        //在以node为根的BST中先序遍历各节点
        private void preOrder(Node node) {
            if(node == null) {
                return;
            }
            System.out.println(node.e);
            preOrder(node.left);
            preOrder(node.right);
        }
        //非递归写法:借助栈
        private List preOrderNR(Node root) {
            ArrayList res = new ArrayList<>();
            if(root == null) {
                return res;
            }
            
            Stack stack = new Stack<>();
            stack.push(root);
            while(!statck.isEmpty()) {
                Node curr = stack.pop();
                res.add(curr.e);
                
                //左右子节点入栈,先入有孩子
                if(curr.right != null) {
                    stack.push(curr.right);    
                }
                if(curr.left != null) {
                    stack.push(curr.left);    
                }
            }
            return res;
        }
        
      • 中序遍历

        public void inOrder() {
            inOrder(root);
        }
        //递归写法
        private void inOrder(Node node) {
            if(node != null) {
                return;
            }
            inOrder(node.left);
            System.out.println(node.e);
            inOrder(node.right);
        }
        //非递归写法
        public void inOrder(Node root) {
            ArrayList res = new ArrayList<>();
            if(root == null)    return res;
            
            Stack stack = new Stack<>();
            Node curr = root;
            while(curr != null || !stack.isEmpty()) {
                //当前节点不为空或栈不为空即可循环
                if(curr != null) {
                    stack.push(curr);
                    curr = curr.left;
                }else{
                    curr = stack.pop();
                    res.add(curr.e);
                    curr = curr.right;
                }
            }
            return res;
        }
        
      • 后序遍历

        public void postOrder() {
            postOrder(root);
        }
        //递归写法
        private void postOrder() {
            if(node != null) {
                return;
            }
            postOrder(node.left);
            postOrder(node.right);
            System.out.println(node.e);
        }
        //非递归写法
        private void postOrderNR(Node root) {
            if(root == null) {
                return;
            }
            Stack traStack = new Stack<>();
            Stack resStack = new Stack<>();
            traStack.push(root);
            while(!traStack.isEmpty()) {
                Node curr = traStack.pop();
                resStack.push(curr);
                if(curr.left != null) {
                    traStack.push(curr.left);
                }
                if(curr.right != null) {
                    traStack.push(curr.right);
                }
            }
            while(!resStack.isEmpty()) {
                Node curr = resStack.pop();
                System.out.println(curr.e);
            }
        }
        
      • 层序遍历

        //借助队列
        private void levelOrder() {
            if(root == null) {
                    //空树
                    return;
            }
            
            Queue queue = new LinkedList<>();
            queue.add(root);
            while(!queue.isEmpty()) {
                Node curr = queue.remove();
                System.out.println(curr.e);
                
                if(curr.left != null) {
                    queue.add(curr.left);
                }
                if(curr.right != null) {
                    queue.add(curr.right);
                }
            }
        }
        

你可能感兴趣的:(二叉搜索树(BST))