二分搜索树添加新元素60,
60>41(根节点),所以一定要插入到41的右子树。
接着在和58比较
1 public class BST<E extends Comparable<E>> {//对于二分搜索树所存储的内容支持泛型,所以在这里写一个E,此外二分搜索树不是支持所有的类型,对这个类型必须要有限制, 2 //这个限制是这个类型必须拥有可比较性,放到代码中,就必须对E进行限制,即E extends Comparable<E>(E要满足可比较性) 3 4 private class Node { //声明节点类 5 public E e; //节点可以存放元素e 6 public Node left, right; //成员变量 7 8 public Node(E e) { //node的构造函数,用户传来一个e 9 this.e = e; //this.e等于用户传来的e(用户传来的参数和节点类成员变量元素均用e表示,所以节点存放元素用this.e表示) 10 left = null; 11 right = null; 12 } 13 } 14 //二分搜索树的成员变量root、size 15 private Node root; //root:根节点 16 private int size; //size:记录二分搜索树存储了多少元素 17 18 public BST(){ //二分搜索树的构造函数 19 root = null; //初始化时二分搜索树一个元素也没有存,根节点root为空 20 size = 0; 21 } 22 23 public int size(){ 24 return size; 25 } 26 27 public boolean isEmpty(){ 28 return size == 0; 29 } 30 31 // 向二分搜索树中添加新的元素e 32 public void add(E e){ 33 34 if(root == null){ 35 root = new Node(e); 36 size ++; 37 } 38 else 39 add(root, e); 40 } 41 42 // 向以node为根的二分搜索树中插入元素e,递归算法 43 private void add(Node node, E e){ 44 //-------------递归的终止条件-------------------// 45 if(e.equals(node.e)) //先检查一下要插入的元素e是否等于node的e,如果等于的话,其实就等于我们要插入的元素在二分搜索树中已经有啦。对于这种情况直接return 46 return; 47 else if(e.compareTo(node.e) < 0 && node.left == null){ //否则,如果要插入的e小于根节点node的e,且node的左子树为空,插入node的左子树 48 node.left = new Node(e); 49 size ++; 50 return; 51 } 52 else if(e.compareTo(node.e) > 0 && node.right == null){ 53 node.right = new Node(e); 54 size ++; 55 return; 56 } 57 //-------------递归的终止条件----结束---------------// 58 59 //--------------递归调用------------------// 60 //如果没有在递归的终止条件成功的return回去的话,就会根据二分搜索树固有的递归结构来看是向节点的左子树插入元素e还是向节点的右子树插入元素e 61 if(e.compareTo(node.e) < 0)//如果要插入的e小于根节点node的e 62 add(node.left, e); 63 else //e.compareTo(node.e) > 0 64 add(node.right, e); 65 } 66 }
对于二分搜索树的插入操作现在这么写是比较复杂的,在下一小节将改进代码,算法没有变化,但会让代码简洁很多。通过下一节,会让大家体会对于递归算法来说,一方面有不同是写法,另一方面终止条件也会有不同的考量。
6-4 改进添加操作:深入理解递归终止条件
这个递归函数的终止条件非常的臃肿,因为要考虑它的左孩子是不是空、右孩子是不是为空
事实上,空本身也是一颗二叉树,如果二叉树为空的话,此时肯定要插入一个节点,
完整代码如下:
1 public class BST<E extends Comparable<E>> { 2 3 private class Node { 4 public E e; 5 public Node left, right; 6 7 public Node(E e) { 8 this.e = e; 9 left = null; 10 right = null; 11 } 12 } 13 14 private Node root; 15 private int size; 16 17 public BST(){ 18 root = null; 19 size = 0; 20 } 21 22 public int size(){ 23 return size; 24 } 25 26 public boolean isEmpty(){ 27 return size == 0; 28 } 29 30 // 向二分搜索树中添加新的元素e 31 public void add(E e){ 32 root = add(root, e); 33 } 34 35 // 向以node为根的二分搜索树中插入元素e,递归算法 36 // 返回插入新节点后二分搜索树的根 37 private Node add(Node node, E e){ 38 if(node == null){ 39 size ++; 40 return new Node(e); 41 } 42 //不管是左子树插入元素还是右子树插入元素,插入完成后,都将当前node的左孩子node.left 、右孩子node.right进行重新赋值,node也会得到更新,最后return node;,返回插入新节点后二分搜索树的根 43 if(e.compareTo(node.e) < 0) 44 node.left = add(node.left, e); 45 else if(e.compareTo(node.e) > 0) 46 node.right = add(node.right, e); 47 48 return node; 49 } 50 }