二叉查找树

原帖地址 http://www.iteye.com/topic/561590

 

  1 import java.util.Collection;
  2 import java.util.Iterator;
  3 import java.util.NoSuchElementException;
  4 
  5 public class BinarySearchTree<E extends Comparable<E>> 
  6 {
  7     
  8     public static void main(String[] args)
  9     {
 10         BinarySearchTree<Integer> bst = new BinarySearchTree<Integer>();
 11         bst.add(50);  
 12         bst.add(37);  
 13         bst.add(75);  
 14         bst.add(25);  
 15         bst.add(61);  
 16         bst.add(15);  
 17         bst.add(30);  
 18         bst.add(55);  
 19         bst.add(68);  
 20         bst.add(28);  
 21         bst.add(32);  
 22         bst.add(59);  
 23         bst.add(36);  
 24         bst.add(36);
 25         
 26         //是否包含  
 27         System.out.println(bst.contains(36));//true  
 28         System.out.println(bst.contains(38));//false  
 29   
 30         //大小  
 31         System.out.println(bst.size());//13  
 32   
 33         //遍历  
 34         Iterator<Integer> itr = bst.iterator();  
 35         while (itr.hasNext()) {  
 36             //15 25 28 30 32 36 37 50 55 59 61 68 75  
 37             System.out.print(itr.next() + " ");  
 38         }  
 39         System.out.println();  
 40   
 41   
 42         //删除根叶子节点36  
 43         bst.remove(36);  
 44         System.out.println(bst.size());//12  
 45         itr = bst.iterator();  
 46         while (itr.hasNext()) {  
 47             //15 25 28 30 32 37 50 55 59 61 68 75  
 48             System.out.print(itr.next() + " ");  
 49         }  
 50         System.out.println();  
 51   
 52         //删除只有一个左子节点的节点37  
 53         bst.remove(37);  
 54         System.out.println(bst.size());//11  
 55         itr = bst.iterator();  
 56         while (itr.hasNext()) {  
 57             //15 25 28 30 32 50 55 59 61 68 75   
 58             System.out.print(itr.next() + " ");  
 59         }  
 60         System.out.println();  
 61   
 62         //删除只有一个右子节点的节点55  
 63         bst.remove(55);  
 64         System.out.println(bst.size());//10  
 65         itr = bst.iterator();  
 66         while (itr.hasNext()) {  
 67             //15 25 28 30 32 50 59 61 68 75   
 68             System.out.print(itr.next() + " ");  
 69         }  
 70         System.out.println();  
 71   
 72         //删除有左右子节点的根节点50  
 73         bst.remove(50);  
 74         System.out.println(bst.size());//9  
 75         itr = bst.iterator();  
 76         while (itr.hasNext()) {  
 77             //15 25 28 30 32 59 61 68 75   
 78             System.out.print(itr.next() + " ");  
 79         }  
 80         System.out.println();  
 81   
 82         //下面通过迭代器删除节点根节点59  
 83         itr = bst.iterator();  
 84         while (itr.hasNext()) {  
 85             if (itr.next() == 59) {  
 86                 itr.remove();//删除最近一次next返回的节点  
 87                 break;  
 88             }  
 89         }  
 90   
 91         while (itr.hasNext()) {  
 92             //61 68 75  
 93             System.out.print(itr.next() + " ");  
 94             itr.remove();  
 95         }  
 96   
 97         System.out.println();  
 98         System.out.println(bst.size());//5 
 99     }
100     
101     
102     private Node root;
103     
104     private int size;
105     
106     
107     public BinarySearchTree()
108     {
109         root = null;
110     }
111     
112     
113     /*
114      * 二叉树插入操作,如果插入节点大于
115      */
116     public boolean add(E e)
117     {
118         Node<E> x = root, y = null;
119         int compare = 0;
120         
121         while (x != null) {
122             // y为每次循环x的父节点
123             y = x;
124             compare = e.compareTo(x.value);
125 
126             /*
127              * 插入节点于当前结点相同则直接返回False
128              * 如果插入节点e如比当前节点x小则将当前节点e指向当前节点的左节点e.left
129              * 否则则将当前节点e指向当前结点右节点e.right
130              */
131             if (compare == 0) return false;
132             
133             if (compare == 1)
134                 x = x.right;
135             else
136                 x = x.left;
137         }
138         
139         if (y == null) {
140             // y为空则表示root为空
141             root = new Node(e, null);
142         }
143         else {
144             // 根据之前判断创建新节点并指定为父节点y的左子节点或右子节点
145             if (compare == 1)
146                 y.right = new Node(e, y);
147             else
148                 y.left = new Node(e, y);
149         }
150         size++;
151         return true;
152     }
153     
154     
155     public boolean contains(E e)
156     {
157         return getNode(e) != null;
158     }
159     
160     
161     private Node<E> getNode(E e)
162     {
163         Node<E> node = root;
164         int compare;
165         
166         while (node != null) {
167             compare = e.compareTo(node.value);
168             
169             if (compare == 0) return node;
170             if (compare == 1) 
171                 node = node.right;
172             else
173                 node = node.left;
174         }
175         
176         return null;
177     }
178     
179     
180     public boolean remove(E e)
181     {
182         // 如果为空则直接返回
183         Node<E> node = getNode(e);
184         if (node == null) return false;
185         removeNode(node);
186         return true;
187     }
188     
189     
190     /*
191      * 如果删除节点n是叶子节点,则直接删除该节点
192      * 如果删除节点只有一个子节点,则将n的子节点与n的父节点直接连接,然后删除节点n
193      * 如果删除节点n有两个子节点,则使用中序立遍历方式得到直接前置节点c或直接后继节点c得知代替节点n的值,然后删除c 
194      */
195     private void removeNode(Node<E> node)
196     {
197         // 有两个子节点
198         if (node.left != null && node.right != null) {
199             Node<E> child = intervalNode(node);
200             node.value = child.value;
201             node = child;
202         }
203         
204         // 没有子节点,自身为叶子节点
205         if (node.left == null && node.right == null) {
206             // 
207             if (node.parent == null) {
208                 root = null;
209             }
210             else {
211                 if (node == node.parent.left)
212                     node.parent.left = null;
213                 else
214                     node.parent.right = null;
215             }
216         }
217         else {
218             // 只有一个节点的情况
219             Node<E> replace;
220             
221             replace = node.left != null ? node.left : node.right;
222             
223             replace.parent = node.parent;
224             
225             if (node.parent == null) {
226                 root = replace;
227             }
228             else if (node == node.parent.left) {
229                 node.parent.left = replace;
230             }
231             else {
232                 node.parent.right = replace;
233             }
234         }
235         node.parent = null;
236         node.left = node.right = null;
237         size--;
238     }
239     
240     
241     /*
242      * 查找中序遍历的直接后继节点
243      * 
244      * 如果待查找的节点有右子树,则后继节点一定在右子树上,此时右子树上的某个节点可能成为后 
245      * 继节点:一是如果待查节点的右子树没有左子树(有没有右子树无所谓)时,直接就返回该待查节点 
246      * 的右子节点;二是如果待点节点的右子节点有左子树,则查找右子节点的最左边的左子树节点(注, 
247      * 该节点一点是左叶子节点或只有一个右子节点的左节点,查找过程要一直向左,即遍历时只向左拐, 
248      * 不可向右)
249      * 
250      * 如果待查找的节点没有右子树,则需要从该节点向根的方向遍历(不可向左或右拐),后继节点只 
251      * 可能在祖宗节点中产生(包括父节点与根节点在内),此情况分两种:一种就是待查节点为某节点的左 
252      * 子树,则此时的后继为父节点;第二种就是当待查节点为某个节点的右子树时,则需沿根的方向向上找, 
253      * 一直找到第一个有左子树的祖宗节点即为后继节点,或到根为止还没有找到(则该节点只可能为中序遍 
254      * 历的最后节点
255      */
256     private Node intervalNode(Node node)
257     {
258         if (node == null) {
259             return null;
260         }
261         else if (node.right != null) {
262             /* 
263              * 查找50节点的直接后继,查找结果为55 
264              *            50 
265              *             \ 
266              *             75 
267              *             / 
268              *            61 
269              *            /\ 
270              *           55 68 
271              *            \ 
272              *            59               
273              */ 
274             
275             Node<E> child = node.right;
276             while (child.left != null) {
277                 child = child.left;
278             }
279             return child;
280         }
281         else {
282             /* 
283              * 没有右子树的节点且为父节点的右子节点36的直接后继为37,同样节点68的直接后继为75 
284              * 没有右子树的节点且为父节点的左子节点37的直接后继为50,同样节点28的直接后继为30 
285              * 75为最后节点,所以直接后继为null 
286              *  
287              *                 50 
288              *                 /\ 
289              *                37 75 
290              *                /   / 
291              *               25   61  
292              *               /\   /\ 
293              *             15 30 55 68  
294              *                /\  \ 
295              *              28 32 59 
296              *                  \ 
297              *                  36 
298              *                   / 
299              *                  35 
300              */ 
301             
302             Node<E> parent = node.parent;
303             Node<E> current = node;
304             
305             while (parent != null && current == parent.right) {
306                 current = parent;
307                 parent = parent.parent;
308             }
309             return parent;
310         }
311     }
312     
313     
314     public int size()
315     {
316         return size;
317     }
318     
319     
320     public Iterator<E> iterator()
321     {
322         return new TreeIterator();
323     }
324     
325     
326     public class TreeIterator implements Iterator<E>
327     {
328         private Node<E> lastReturned;
329         
330         private Node<E> next;
331         
332         private Node<E> endNode;
333 
334         
335         public TreeIterator()
336         {
337             next = root;
338             if (next != null) {
339                 while (next.left != null) {
340                     next = next.left;
341                 }
342             }
343         }
344         
345         public boolean hasPreVious()
346         {
347             return (next != null && intervalNode(next) != null) || endNode != null;
348         }
349         
350         
351         public E previous()
352         {
353             if (next != null && intervalNode(next) == null) {
354                 throw new NoSuchElementException();
355             }
356             
357             if (endNode != null) {
358                 lastReturned = next = endNode;
359                 endNode = null;
360             }
361             else {
362                 lastReturned = next = intervalNode(next);
363             }
364             return lastReturned.value;
365         }
366         
367         public boolean hasNext() 
368         {
369             return next != null;
370         }
371 
372         public E next() 
373         {
374             if (next == null)
375                 throw new NoSuchElementException();
376             
377             lastReturned = next;
378             next = intervalNode(next);
379             
380             if (next == null) {
381                 endNode = lastReturned;
382             }
383             return lastReturned.value;
384         }
385 
386         
387         public void remove() 
388         {
389             if (lastReturned == null) {
390                 throw new IllegalStateException();
391             }
392             
393             if (lastReturned.left != null && lastReturned.right != null) {
394                 next = lastReturned;
395             }
396             removeNode(lastReturned);
397             lastReturned = null;
398         }
399 
400     }
401 
402     
403     public void preOrder(Collection<E> collect)
404     {
405         preOrder(root, collect);
406     }
407     
408     
409     private final void preOrder(Node<E> n, Collection<E> collect)
410     {
411         if (n != null) {
412             collect.add(n.value);
413             preOrder(n.left, collect);
414             preOrder(n.right, collect);
415         }
416     }
417     
418     
419     public void inOrder(Collection<E> collect)
420     {
421         inOrder(root, collect);
422     }
423     
424     
425     private void inOrder(Node<E> n, Collection<E> collect)
426     {
427         if (n == null) return;
428         inOrder(n.left, collect);
429         collect.add(n.value);
430         inOrder(n.right, collect);
431     }
432     
433     
434     public void postOrder(Collection<E> collect)
435     {
436         postOrder(root, collect);
437     }
438     
439     
440     private final void postOrder(Node<E> n, Collection<E> collect)
441     {
442         if (n == null) return;
443         postOrder(n.left, collect);
444         postOrder(n.right, collect);
445         collect.add(n.value);
446     }
447     
448     
449     private class Node<E>
450     {
451         private E value;
452         
453         private Node parent;
454         
455         private Node left;
456         
457         private Node right;
458         
459         public Node(E value, Node parent)
460         {
461             this.value = value;
462             this.parent = parent;
463         }
464     }
465 }
posted @ 2012-07-11 15:39  rilley  阅读(250)  评论(0编辑  收藏  举报