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
时间: 2024-08-01 10:59:23

JAVA BST的实现的相关文章

[LeetCode][Java]Contains Duplicate III

Contains Duplicate III Given an array of integers, find out whether there are two distinct indices i and j in the array such that the difference between nums[i] and nums[j] is at most t and the difference between i and j is at most k. 数组中是否存在两个元素,他们的

Kth Largest Element in a Stream

Design a class to find the kth largest element in a stream. Note that it is the kth largest element in the sorted order, not the kth distinct element. Your KthLargest class will have a constructor which accepts an integer k and an integer array nums,

BST(二叉搜索树) Java 实现解析

1.二叉搜索树的定义:一颗树的所有左子树都比根小,所有右子树都比根大,成为二叉搜索树. 2.该BST树实现了9个重要方法,分别是关键字查找,插入,删除,删除节点后续节点查找,前序遍历,中序遍历,后序遍历,获取最大节点,获取最小节点. 3.以下是Java的代码实现: //定义Node类,拥有元素值,节点名称,左孩子节点,右孩子节点,4个成员变量.class Node { int element; String name; Node leftChild; Node rightChild; publi

Java实现查找树(BST,AVL,BTree,Trie)

BST 二叉排序树是一种非常简单的排序树(或者说查找树) 包括两种操作 添加 添加的元素永远是叶子节点 删除 叶子节点,直接删除 非叶子节点 2.1. 只有左子树或者只有右子树,直接用左子树或者右子树代替待删除节点 2.2. 如果左右子树都存在,则将右子树接到左子树的最右边节点的右子树下,这样就依然保持了有序 import java.util.*; /* * 二分法查找 */ public class BST { public static Node root = null; public st

Java AVL、BST编程作业代写、代做JDK实验

Java AVL.BST编程作业代写.代做JDK实验1 IntroductionNeeding a way to manage all your PlayStation friends, you decide to build a backendsystem for adding, removing and maintaining them. The idea is to organiseyour friends so you can search for individuals, search

LeetCode算法题-Convert BST to Greater Tree(Java实现)

这是悦乐书的第255次更新,第268篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第122题(顺位题号是538).给定二进制搜索树(BST),将其转换为更大树,使原始BST的每个键都更改为原始键加上所有键的总和大于BST中的原始键.例如: 输入:二进制搜索树的根,如下所示: 5 / 2 13 输出:大树的根,如下所示: 18 / 20 13 本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试. 0

LeetCode算法题-Minimum Distance Between BST Nodes(Java实现-四种解法)

这是悦乐书的第314次更新,第335篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第183题(顺位题号是783).给定具有根节点值的二叉搜索树(BST),返回树中任何两个不同节点的值之间的最小差值.示例: 给定的树[4,2,6,1,3,null,null]由下图表示: 4 / 2 6 / \ 1 3 输出:1 说明:请注意,root是TreeNode对象,而不是数组.该树中的任意节点最小差值为1,它发生在节点1和节点2之间,也发生在节点3和节点2之间. 注意: BS

纯数据结构Java实现(4/11)(BST)

个人感觉,BST(二叉查找树)应该是众多常见树的爸爸,而不是弟弟,尽管相比较而言,它比较简单. 二叉树基础 理论定义,代码定义,满,完全等定义 不同于线性结构,树结构用于存储的话,通常操作效率更高.就拿现在说的二叉搜索树(排序树)来说,如果每次操作之后会让剩余的数据集减少一半,这不是太美妙了么?(当然不当的运用树结构存储,也会导致从 O(logN) 退化到 O(n)). 值得说明,O(logN) 其实并不准确,准确来说应该说 O(树的高度) 定义&性质&行话 树里面常见的二叉树: BST,

“中兴捧月”比赛之——二叉查找树(BST)树的最短路径Java求解

问题描述: BST树,又称二叉查找树,求其到所有叶子节点路径的最小值 测试用例一:  10 5 20 返回15: 测试用例二: 100 20 70 110 120 10 null null 89 null null null null 返回130: 程序代码实现: 1 package examination.written; 2 3 /** 4 * 5 * @author ZhuXY 6 * @time 2016-6-12 下午9:57:53 7 * 8 */ 9 public class BS