码迷,mamicode.com
首页 > 其他好文 > 详细

二叉查找树的递归实现及递归分析

时间:2016-04-14 12:08:52      阅读:262      评论:0      收藏:0      [点我收藏+]

标签:

一,树由结点组成

结点的定义如下:

 1     private static class BinaryNode<T>{
 2         T element;
 3         BinaryNode left;
 4         BinaryNode right;
 5         
 6         public BinaryNode(T element) {
 7             this(element, null, null);
 8         }
 9         
10         public BinaryNode(T element, BinaryNode<T>left, BinaryNode<T>right) {
11             this.element = element;
12             this.left = left;
13             this.right = right;
14         }
15     }

 

二,二叉查找树 类

对于树,需要有根结点。BinaryNode<T>以静态内部类方式声明在BinarySearchTree<T>中。静态内部类的功能就是:静态内部类的对象的创建不需要依赖其外部类的对象。

BinarySearchTree采用默认构造方法创建对象,然后调用 insert 方法向树中添加节点。

public class BinarySearchTree<T extends Comparable<? super T>> {
    
    ......//BinaryNode<T>的声明
    
    private BinaryNode<T> root;

    ....... // 二叉查找树中的方法

 

三,二叉查找树的一些方法的递归实现及分析

1) insert(T ele),向二叉查找树中插入一个元素。插入元素之后,返回树根节点。

正确版本:

 1 private BinaryNode<T> insert(T ele, BinaryNode<T> root){
 2         if(root == null)
 3             return new BinaryNode<T>(ele);
 4         int compareResult = ele.compareTo(root.element);
 5         if(compareResult > 0)
 6             root.right = insert(ele, root.right);
 7         else if(compareResult < 0)
 8             root.left = insert(ele, root.left);
 9         else
10             ;
11         return root;
12     }

 

错误版本一:

 1     private BinaryNode<T> insert1(T ele, BinaryNode<T> root){
 2         if(root == null)
 3             return new BinaryNode<T>(ele);
 4         
 5         int compareResult = ele.compareTo(root.element);
 6         if(compareResult > 0)
 7             return insert(ele, root.right);
 8         else if(compareResult < 0)
 9             return insert(ele, root.left);
10         else
11             return root;
12         
13     }

这种版本的递归,返回的是:最后一层递归调用时,root所指向的节点。最后一层递归调用发生在叶子节点上,故返回的root是最后一个插入的元素。

判断递归调用每一层的返回值时,可按照“压栈”的顺序进行分析。

如,上面程序当运行到第7行时,执行递归调用,那么会将当前的环境压入栈中,保存起来。然后执行下一层的方法调用。

当下面的递归调用结束后,程序返回到第7行。继续向后执行,可以看出第8行的 else if 和 第10行的 else的条件都不成立(因为程序已经在第7行条件成立了)

错误版本二:

 1     private BinaryNode<T> insert2(T ele, BinaryNode<T> root){
 2         if(root == null)
 3             return new BinaryNode<T>(ele);
 4         int compareResult = ele.compareTo(root.element);
 5         if(compareResult > 0)
 6             root = insert2(ele, root.right);
 7         else if(compareResult < 0)
 8             root = insert2(ele, root.left);
 9         else
10             ;
11         return root;
12     }


版本二的错误和版本一一样,都没有建立起父节点与左右孩子节点的连接。因此,最终得到的树根节点指向的是最后一个插入的元素。

 

2)查找二叉树中元素最大的节点

正确版本:

 1  /*
 2      * 关于尾递归的返回值,该方法只会返回二个值: null 和 ‘root‘
 3      * root 是最后一层递归调用时findMax的 root 参数
 4      */
 5     private BinaryNode<T> findMax(BinaryNode<T> root){
 6         if(root == null)
 7             return null;
 8         if(root.right == null)
 9             return root;
10         else
11             return findMax(root.right);
12     }

只有当树为空时,才返回null。第一个if判断才会执行,否则第一个if永远不会执行。

错误版本:

1     private BinaryNode<T> findMax1(BinaryNode<T> root){
2         if(root == null)
3             return null;
4         else
5             return findMax(root.right);
6     }
7     

该findMax递归版本,不管root是否为空,不管树中有多少个节点,返回的值都为null。从中可以看出,这种形式的递归返回值,由其基准条件来决定。

 

二叉查找树完整实现代码如下:

  1 public class BinarySearchTree<T extends Comparable<? super T>> {
  2     
  3     
  4     private static class BinaryNode<T>{
  5         T element;
  6         BinaryNode left;
  7         BinaryNode right;
  8         
  9         public BinaryNode(T element) {
 10             this(element, null, null);
 11         }
 12         
 13         public BinaryNode(T element, BinaryNode<T>left, BinaryNode<T>right) {
 14             this.element = element;
 15             this.left = left;
 16             this.right = right;
 17         }
 18     }
 19     
 20     private BinaryNode<T> root;
 21     
 22     
 23     public BinarySearchTree() {
 24         root = null;
 25     }
 26     
 27     public void makeEmpty(){
 28         root = null;
 29     }
 30     public boolean isEmpty(){
 31         return root == null;
 32     }
 33     
 34     public boolean contains(T ele){
 35         return contains(ele, root);
 36     }
 37     
 38     private boolean contains(T ele, BinaryNode<T> root){
 39         if(root == null)
 40             return false;
 41         int compareResult = ele.compareTo(root.element);
 42         if(compareResult > 0)
 43             return contains(ele, root.right);
 44         else if(compareResult < 0)
 45             return contains(ele, root.left);
 46         else
 47             return true;
 48     }
 49     
 50     
 51     public BinaryNode<T> findMax(){
 52         return findMax(root);
 53     }
 54     
 55     /*
 56      * 关于尾递归的返回值,该方法只会返回二个值: null 和 ‘root‘
 57      * root 是最后一层递归调用时findMax的 root 参数
 58      */
 59     private BinaryNode<T> findMax(BinaryNode<T> root){
 60         if(root == null)
 61             return null;
 62         if(root.right == null)
 63             return root;
 64         else
 65             return findMax(root.right);
 66     }
 67     
 68     public void insert(T ele){
 69         root =  insert(ele, root);// 每次插入操作都会‘更新‘根节点.
 70     }
 71 
 72     
 73     private BinaryNode<T> insert(T ele, BinaryNode<T> root){
 74         if(root == null)
 75             return new BinaryNode<T>(ele);
 76         int compareResult = ele.compareTo(root.element);
 77         if(compareResult > 0)
 78             root.right = insert(ele, root.right);
 79         else if(compareResult < 0)
 80             root.left = insert(ele, root.left);
 81         else
 82             ;
 83         return root;
 84     }
 85     
 86     public void preOrder(BinaryNode<T> root){
 87         if(root == null)
 88             return;
 89         System.out.print(root.element + " ");
 90         preOrder(root.left);
 91         preOrder(root.right);
 92     }
 93     
 94     
 95     
 96     
 97     public static void main(String[] args) {
 98         BinarySearchTree<String> tree = new BinarySearchTree<>();
 99         tree.insert("e");
100         tree.insert("d");
101         tree.insert("c");
102         tree.insert("f");
103         tree.insert("g");
104         
105         System.out.println(tree.contains("g"));
106         System.out.println(tree.contains("h"));
107         tree.preOrder(tree.root);
108     }
109 }

 

二叉查找树的递归实现及递归分析

标签:

原文地址:http://www.cnblogs.com/hapjin/p/5390451.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!