标签:
一,树由结点组成
结点的定义如下:
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