• JAVA BST的实现


      花了几个小时,终于实现了BST,虽然比较简单,但感觉还是不错。

      1 public class BinarySearchTree {
      2     TreeNode rootNode=null;
      3     private int size=0;
      4     public BinarySearchTree()
      5     {}
      6     public BinarySearchTree(int [] values)
      7     {
      8         for(int i=0;i<values.length;i++)
      9         {
     10             insert(values[i]);
     11         }
     12     }
     13     public int size()
     14     {
     15         System.out.println("size="+size);
     16         return size;
     17     }
     18     public void insert(int value)
     19     {
     20         if(rootNode==null)
     21         {
     22             rootNode=new TreeNode(value);
     23             size++;
     24             return;
     25         }
     26         TreeNode treeNode=new TreeNode(value);
     27         insert(rootNode, treeNode);
     28         size++;
     29     }
     30     /**
     31      * 每次插入的都是叶子节点
     32      * @param root
     33      * @param newNode
     34      */
     35     
     36     private void insert(TreeNode root,TreeNode newNode)
     37     {
     38         //没有左子树或右子树的情况
     39         if(root.left==null && root.value>newNode.value)
     40         {
     41             root.left=newNode;
     42             newNode.parent=root;
     43             return;
     44         }
     45         if(root.right==null && root.value<newNode.value)
     46         {
     47             root.right=newNode;
     48             newNode.parent=root;
     49         }
     50         if(root.value>newNode.value) insert(root.left,newNode);
     51         else if(root.value<newNode.value) insert(root.right,newNode);
     52     }
     53     
     54     /**
     55      * 删除节点的办法
     56      * 假如目标节点的左子树为空,直接将右子树的根取代目标节点
     57      * 假如目标节点的右子树为空,直接将左子树的根取代目标节点
     58      * 假如目标节点的左右子树都不为空,将左边子树的最右边的叶子节点  或  右子树的最左边的叶子节点取代目标节点
     59      * 这里取右子树最小值,共有两种情况
     60      * 1、这个最小值是叶子节点,
     61      * 2、这个最小值不是叶子节点,有一颗右子树
     62      * 对于第一种直接将叶子节点的值赋给要删除的节点,然后将双亲的左子树置空
     63      * 对于第二种将叶子节点的值赋给要删除的节点,接着将双亲的右子树指向被删节点的右子树。
     64      * 上面两种情况合起来就是假如有右子树,就将右子树链接到该节点的双亲上
     65      * @param value
     66      */
     67     public void delete(int value)
     68     {
     69         TreeNode node=searchNode(rootNode, value);
     70         if(node==null)
     71         {
     72             System.out.println("node "+value+" doesn't exist!");
     73             return;
     74         }
     75         size--;
     76         //如果左右子树都为空 直接获取双亲
     77         if(node.left==null && node.right==null)
     78         {
     79             System.out.println("左右为空");
     80             if(isLeftLeaf(node)) node.parent.left=null;//左子树
     81             else if(isRightLeaf(node)) node.parent.right=null;//右子树
     82             else rootNode=null;  //既没有子树,又没有双亲,只能是单个的根节点了,直接删除
     83             return;
     84         }
     85         
     86         //存在左子树
     87         if(node.left!=null && node.right==null)
     88         {
     89             System.out.println("存在左子树");
     90             if(isLeftLeaf(node)) node.parent.left=node.left;
     91             else if(isRightLeaf(node)) node.parent.right=node.left;
     92             else rootNode.left=node.left;
     93             return;
     94         }
     95         
     96         //存在右子树
     97         if(node.left==null && node.right!=null)
     98         {
     99             System.out.println("存在右子树");
    100             if(isLeftLeaf(node)) node.parent.left=node.right;
    101             else if(isRightLeaf(node)) node.parent.right=node.right;
    102             else rootNode.right=node.right;
    103             return;
    104         }
    105         
    106         //左右子树都存在
    107         if(node.left!=null && node.right!=null)
    108         {
    109             System.out.println("左右不为空");
    110             TreeNode tempNode=node.right;
    111             while(tempNode.left!=null)
    112                 tempNode=tempNode.left;
    113             //将该节点的值赋给node
    114             node.value=tempNode.value;
    115             
    116             if(tempNode.right!=null)
    117             {
    118                 if(isLeftLeaf(tempNode)) tempNode.parent.left=tempNode.right;
    119                 else if(isRightLeaf(tempNode)) tempNode.parent.right=tempNode.right;
    120                 else rootNode.right=tempNode.right;
    121             }
    122             else 
    123             {
    124                 if(isLeftLeaf(tempNode)) tempNode.parent.left=null;//左子树
    125                 else if(isRightLeaf(tempNode)) tempNode.parent.right=null;//右子树
    126                 else rootNode=null;  //既没有子树,又没有双亲,只能是单个的根节点了,直接删除
    127             }
    128         }
    129     }
    130     //先判断是否有双亲,再判断该节点是否等于双亲的左子树
    131     public boolean isLeftLeaf(TreeNode node)
    132     {
    133         
    134         if(node.parent==null)
    135             return false;
    136         TreeNode leftNode=node.parent.left;
    137         return leftNode==node;
    138     }
    139     
    140     public boolean isRightLeaf(TreeNode node)
    141     {
    142         if(node.parent==null)
    143             return false;
    144         TreeNode rightNode=node.parent.right;
    145         return rightNode==node;
    146     }
    147     
    148     public void preOrder()
    149     {
    150         if(rootNode==null)
    151         {
    152             System.out.println("tree is null");
    153             return ;
    154         }
    155         preOrder(rootNode);
    156     }
    157     
    158     private void preOrder(TreeNode treeNode)
    159     {
    160         if(treeNode!=null)
    161         {
    162             System.out.println(treeNode.value);
    163             preOrder(treeNode.left);
    164             preOrder(treeNode.right);
    165         }
    166     }
    167     
    168     public TreeNode searchNode(int value)
    169     {
    170         return searchNode(rootNode,value);
    171     }
    172     
    173     private TreeNode searchNode(TreeNode treeNode,int value)
    174     {
    175         if(treeNode==null)
    176             return null;
    177         if(value<treeNode.value)
    178             return searchNode(treeNode.left, value);
    179         else if(value>treeNode.value)
    180             return searchNode(treeNode.right, value);
    181         else
    182             return treeNode;
    183     }
    184     
    185     public void inOrder()
    186     {
    187         if(rootNode==null)
    188         {
    189             System.out.println("tree is null");
    190             return ;
    191         }
    192         inOrder(rootNode);
    193     }
    194     
    195     private void inOrder(TreeNode treeNode)
    196     {
    197         if(treeNode!=null)
    198         {
    199             inOrder(treeNode.left);
    200             System.out.println(treeNode.value);
    201             inOrder(treeNode.right);
    202         }
    203     }
    204     
    205     public class TreeNode
    206     {
    207         private int value;
    208         TreeNode right;
    209         TreeNode left;
    210         TreeNode parent;
    211         
    212         public TreeNode()
    213         {
    214             this.value=0;
    215         }
    216         
    217         public TreeNode(int value)
    218         {
    219             this.value=value;
    220         }
    221         
    222         public int value()
    223         {
    224             return value;
    225         }
    226     }
    227 }

    测试代码

          public static void main(String[] args) throws Exception{
              int[] data={16,6,2,5,1,18,7};
              BinarySearchTree bst=new BinarySearchTree(data);
              System.out.println(bst.searchNode(2).parent.value());
              System.out.println(bst.searchNode(6).right.value());
              bst.insert(17);
              System.out.println(bst.searchNode(17).parent.value());
              bst.insert(25);
              System.out.println(bst.searchNode(18).right.value());
              bst.delete(6);
              System.out.println(bst.searchNode(16).left.value());
              bst.delete(1);
              System.out.println(bst.searchNode(2).left);
              bst.delete(16);
              System.out.println(bst.searchNode(18).parent.value());
              bst.delete(18);
              System.out.println(bst.searchNode(17).right.value());
          }

    结果

    6
    7
    18
    25
    左右不为空
    7
    左右为空
    null
    左右不为空
    17
    存在右子树
    25
  • 相关阅读:
    android ListView布局之一(继承listActivity、使用arrayAdapter)
    android your project contains error
    wojilu系统的ORM代码解析[源代码结构分析,ObjectBase基类分析]
    ORM中启用数据库事务
    我记录网站综合系统 技术原理解析[11:ActionProcessor流程wojilu核心]
    互联网,让我们更安全了,还是更危险了【纯讨论】
    不用服务器也能跑的框架wojilu续篇
    使用wojilu 无代码实现 输入框提示 及其背后的原理
    wojilu日志系统可以单独使用
    “我有什么” 和 “你要什么” 框架制作的一些思考
  • 原文地址:https://www.cnblogs.com/maydow/p/4774975.html
Copyright © 2020-2023  润新知