二叉搜索树中的常用方法

  1 package Tree;
  2 
  3 import org.junit.Test;
  4 
  5 class TreeNode {
  6 
  7     int val = 0;
  8     TreeNode left = null;
  9     TreeNode right = null;
 10 
 11     public TreeNode(int val) {
 12         this.val = val;
 13 
 14     }
 15 
 16 }
 17 
 18 public class BinarySearchTree {
 19 
 20     /**
 21      * @param T
 22      *            二叉搜索树的根节点
 23      * @param number
 24      *            要查找的树
 25      * @return 值域为number的节点
 26      */
 27     public TreeNode treeSearch(TreeNode T, int number) {
 28 
 29         if (T == null || T.val == number)
 30             return T;
 31         if (number < T.val)
 32             return treeSearch(T.left, number);
 33         else
 34             return treeSearch(T.right, number);
 35 
 36     }
 37 
 38     // 通过迭代的方式进行搜索
 39     public TreeNode iteratorTreeSearch(TreeNode T, int number) {
 40 
 41         if (T == null || T.val == number)
 42             return T;
 43         TreeNode treeNode = T;
 44         while (treeNode.val != number) {
 45             if (number < treeNode.val)
 46                 treeNode = treeNode.left;
 47             else
 48                 treeNode = treeNode.right;
 49         }
 50         return treeNode;
 51     }
 52 
 53     // 返回节点treeNode的父节点
 54     public TreeNode treeSearchParent(TreeNode T, TreeNode treeNode) {
 55 
 56         if (T == null || T == treeNode)
 57             return null;
 58         TreeNode treeNodeParent = null;
 59         while (treeNode.val != T.val) {
 60             treeNodeParent = T;
 61             if (treeNode.val < T.val)
 62                 T = T.left;
 63             else
 64                 T = T.right;
 65         }
 66         return treeNodeParent;
 67     }
 68 
 69     // 返回二叉搜索树中的最大值的节点
 70     public TreeNode treeMaximum(TreeNode T) {
 71 
 72         if (T == null)
 73             return T;
 74         TreeNode treeNode = T;
 75         while (treeNode.right != null)
 76             treeNode = treeNode.right;
 77         return treeNode;
 78     }
 79 
 80     // 返回二叉搜索树中的最小值的节点
 81     public TreeNode treeMinimum(TreeNode T) {
 82 
 83         if (T == null)
 84             return T;
 85         TreeNode treeNode = T;
 86         while (treeNode.left != null)
 87             treeNode = treeNode.left;
 88         return treeNode;
 89     }
 90 
 91     // 返回节点treeNode的后继,如果没有则返回null
 92     // while循环中的判断条件为引用相等,也就是说传入的节点引用必须是二叉树中该节点的引用
 93     // 也可以用treeNode.val == treeNodeParent.right.val替换,仅仅判断值是否相等
 94     public TreeNode treeSuccessor(TreeNode T, TreeNode treeNode) {
 95 
 96         if (treeNode == null)
 97             return null;
 98         if (treeNode.right != null)
 99             return treeMinimum(treeNode.right);
100         TreeNode treeNodeParent = treeSearchParent(T, treeNode);
101         while (treeNodeParent != null && treeNode == treeNodeParent.right) {
102             treeNode = treeNodeParent;
103             treeNodeParent = treeSearchParent(T, treeNodeParent);
104         }
105         return treeNodeParent;
106     }
107 
108     /**
109      * 将节点z插入到二叉搜索树T中
110      * 
111      * @param T
112      * @param z
113      */
114     public void treeInsert(TreeNode T, TreeNode z) {
115 
116         // 树为空的情况
117         if (T == null) {
118             T = z;
119             return;
120         }
121         // 树非空的情况,假设所有节点都不相同,y始终记录x的父节点
122         TreeNode y = null, x = T;
123         while (x != null) {
124             y = x;
125             if (z.val < x.val)
126                 x = x.left;
127             else
128                 x = x.right;
129         }
130         if (z.val < y.val)
131             y.left = z;
132         else
133             y.right = z;
134     }
135 
136     // 中序遍历二叉搜索树T
137     public void treeInOrder(TreeNode T) {
138 
139         if (T == null)
140             return;
141         treeInOrder(T.left);
142         System.out.print(T.val + ",");
143         treeInOrder(T.right);
144     }
145 
146     // 用一颗以v为根的子树来替代一颗以u为根的子树,使得u的双亲结点成为v的双亲结点
147     // 注意,这里并没有修改结点v的左右指针,由调用者进行修改
148     public void transplant(TreeNode T, TreeNode u, TreeNode v) {
149         TreeNode uParent = treeSearchParent(T, u);
150         // u是根结点的情况
151         if (T == u)
152             T = v;
153         else if (uParent.left == u)
154             uParent.left = v;
155         else if (uParent.right == u)
156             uParent.right = v;
157     }
158 
159     // 二叉搜索树结点删除的真正算法要开始了
160     public void treeDelete(TreeNode T, TreeNode z) {
161         // 找到结点z的直接后继y
162         TreeNode y = treeSuccessor(T, z);
163         // 1,要删除的结点z没有左孩子,无论右孩子是否为空,直接替换
164         if (z.left == null)
165             transplant(T, z, z.right);
166         // 2,要删除的结点z没有右孩子,无论左孩子是否为空,直接替换
167         else if (z.right == null)
168             transplant(T, z, z.left);
169         // 3,要删除的结点z既有左孩子也有右孩子,结点z的直接后继y是结点z的右孩子
170         // 代码还可以再优化一下,这里只是为了条理清晰方便理解
171         else if (z.right == y) {
172             transplant(T, z, y);
173             y.left = z.left;
174         }
175         // 4,要删除的结点z既有左孩子也有右孩子,结点z的直接后继y不是结点z的右孩子
176         else {
177             // 此时y结点的左孩子一定为空
178             transplant(T, y, y.right);
179             transplant(T, z, y);
180             y.right = z.right;
181             y.left = z.left;
182         }
183     }
184 
185     @Test
186     public void testInsert() {
187         TreeNode T = new TreeNode(15);
188         TreeNode treeNode = null;
189         int[] array = { 6, 18, 3, 7, 17, 20, 2, 4, 13, 9 };
190         for (int i = 0; i < array.length; ++i) {
191             treeNode = new TreeNode(array[i]);
192             treeInsert(T, treeNode);
193         }
194         treeInOrder(T);
195         // 测试搜索功能
196         System.out.println();
197         System.out.println(treeSearch(T, 20).val);
198         System.out.println(iteratorTreeSearch(T, 13).val);
199         // 测试最大最小功能
200         System.out.println("最大值为:" + treeMaximum(T).val);
201         System.out.println("最小值为:" + treeMinimum(T).val);
202         // 测试父节点功能
203         System.out
204                 .println("2的父节点为:" + treeSearchParent(T, new TreeNode(2)).val);
205         // 测试前驱后继功能
206         System.out.println("13的后继节点为:"
207                 + treeSuccessor(T, treeSearch(T, 13)).val);
208     }
209 
210     @Test
211     public void testDelete() {
212         // 该二叉搜索树的根节点的值为15
213         TreeNode T = new TreeNode(15);
214         TreeNode treeNode = null;
215         int[] array = { 6, 18, 3, 7, 8, 17, 20, 2, 4, 13, 9, 22 };
216         for (int i = 0; i < array.length; ++i) {
217             treeNode = new TreeNode(array[i]);
218             treeInsert(T, treeNode);
219         }
220         treeInOrder(T);
221         System.out.println();
222         // 测试二叉搜索树中删除结点的功能,删除的四种情况都需要测试
223         treeDelete(T, treeSearch(T, 6));
224         treeInOrder(T);
225     }
226 
227 }

 

转载于:https://www.cnblogs.com/wjf0/p/5873967.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值