二叉搜索树

123 阅读5分钟

如果新增的节点比树上的节点大,则放在右边,如果小放在左边。

特点

特点1
最大元素一定在树的最右边。
最小元素一定在树的最左边。
特点2
二叉搜索树的中序遍历,就是从小到大的排序 (数据排序)。

不足

会产生极左/右的情况,那时的时间复杂度为 o(n)

树的实体类

public class SearchTreeNode {
   public SearchTreeNode right;
   public SearchTreeNode left;
   public int value;
   public SearchTreeNode(int value) {
      this.value = value;
   }
}

添加元素

public class SearchTree {
   SearchTreeNode root = null;
   public void put(int value) {
      root = add(root, value);
   }
   // 递归遍历二叉树插入节点
   private SearchTreeNode add(SearchTreeNode node, int value) {
   // 当节点为null时说明找到了对应的位置
      if (node == null) {
         return new SearchTreeNode(value);
      }
      // 如果value大于当前节点,则放在该节点的右边
      if (value > node.value) {
      // 让节点的右孩子 等于下个节点,
      // 为空时创建新节点,为有孩子赋值
      //  不为空时,进行下一次的递归
         node.right = add(node.right, value);
      } else if (value < node.value) {
       // 让节点的左孩子 等于下个节点,
      // 为空时创建新节点,为左孩子赋值
      //  不为空时,进行下一次的递归
         node.left = add(node.left, value);
      } else {
         node.value = value;
      }
      // 执行到此,所有的递归已经,进行恢复,该节点为头结点(第一个添加进来的元素)
      return node;
   }
   

删除元素

   public void remove(int value) {
      root = remove(root, value);
   }
   // 形成递归
   public SearchTreeNode remove(SearchTreeNode node, int value) {
      if (node == null) {
         return null;
      }
      // 找到要删除的node
      if (value > node.value) {
         node.right = remove(node.right, value);
      } else if (value < node.value) {
         node.left = remove(node.left, value);
      } else//   确定(等于)0要删除的node
        // 节点的左右孩子为null,直接删除该元素,为父节点返回null值。
         if (node.right == null && node.left == null) {
            node = null;
            return null;
         } else if (node.right == null && node.left != null) {  // 节点的有孩子为空,左孩子不为空,返回左孩子,
            SearchTreeNode leftNode = node.left;
            node = null;
            return leftNode;
         } else if (node.right != null && node.left == null) {//右孩子不为空,返回右孩子节点
         SearchTreeNode rightNode = node.right;
            node = null;
            return rightNode;
         } else {
         // 重点,当左右孩子都不为空的时候 ,需要一个节点来替代当前节点。
         // 1,在左子树查找出最大节点
         // 2, 在右子树查找出最小节点
         
            // 查找到 左边最大的node
            SearchTreeNode maxNode = maxNode(node.left);
            // 删除左子树中的最大节点
            maxNode.left = delMaxNode(node.left);
            maxNode.right = node.right;
            node = null;
            return maxNode;
         }
      }
      return node;
   }
   // 删除最大的值,并返回最大值的左孩子,连城一条链
   private SearchTreeNode delMaxNode(SearchTreeNode node) {
      if (node.right == null) {
         SearchTreeNode leftNode = node.left;
         node = null;
         return leftNode;
      }
      node.right =  delMaxNode(node.right); // 构成一条链,删除最右边(大)的的节点
      return node;
   }
   // 最大节点在最右边右孩子为null的值
   private SearchTreeNode maxNode(SearchTreeNode node) {
      if (node.right == null) {
         return node;
      }
      return maxNode(node.right);
   }

输出打印

   
   //打印二叉树
   public void printTree() {
      printMid(root);
   }
   // 前序遍历
   public void printBefore(SearchTreeNode node) {
      if (node == null) {
         return;
      }
      System.out.print(node.value);
      printBefore(node.left);
      printBefore(node.right);
   }
   // 中序遍历
   public void printMid(SearchTreeNode node) {
      if (node == null) {
         return;
      }
      printMid(node.left);
      System.out.print(node.value);
      printMid(node.right);
   }
   public static void main(String[] args) {
      SearchTree treeDemo = new SearchTree();
      treeDemo.put(5);
      treeDemo.put(7);
      treeDemo.put(3);
      treeDemo.put(6);
      treeDemo.put(1);
      treeDemo.put(9);
      treeDemo.put(11);
      treeDemo.put(0);
//    treeDemo.remove(5);
      treeDemo.printTree();
   }
}

二叉搜索树