在二叉查找树中添加元素,改过程相似于树的查找过程,新元素添加为树的叶结点,从根开始,沿着每一个结点中元素所肯定的路径,直到相应地方向上没有子结点为止,此时,将新元素添加为叶结点。html
若是没有其余操做,二叉查找树的树形由元素的添加顺序来决定。java
注:若是输入是彻底有序的,二叉查找树就会退化为一个有序链表,削弱了它自己的价值,以下图所示。git
第三种状况,若是被删除结点有两个子结点,在树的更低层找到一个合适的结点来代替它。被删除结点的子结点成为替代结点的子结点。数据结构
当从二叉查找树中删除有两个子结点的结点是,比较好的办法是用它的中序后继来取代它,即在中序遍历中排在被删元素以后的那个元素(紧邻的下一个值)性能
public interface BinarySearchTreeADT<T> extends BinaryTreeADT<T> { public void addElement(T element); //往树中添加一个元素 public T removeElement(T targetElement); // 从树中删除一个元素 public void removeAllOccurrences(T targetElement); // 从树中删除所指定元素的任何存在 public T removeMin(); //删除树中最小元素 public T removeMax(); // 删除树中最大元素 public T findMin(); //返回一个指向树中最小元素的引用 public T findMax(); //返回一个指向树中最大元素的引用 }
在平衡二叉树中进行查找,比在退化的树中进行查找的效率高不少。在有n个结点的平衡树中进行查找及添加操做的效率是进行O(log2 n)次比较(最长路径的长度)。树越退化,查找及添加操做的时间复杂度越接近O(n),它抵消了使用查找树带来的益处。学习
能够对二叉查找树进行旋转以恢复平衡测试
右旋转3d
1.令根的左子结点变为新的根 2.令原根结点变为新的根结点的右子结点 3.令原根的左子结点的右子结点变为原根结点的新的左子结点
1.令根的右子结点变为新的根 2.令原根结点变为新的根结点的左子结点 3.令原根的右子结点的左子结点变为原根结点的新的右子结点
并不是全部的不平衡状况均可以用一个单一的旋转解决,若是不平衡性是由根的右子结点的左子树的长路径引起的,则必须先绕那个异常子树执行一次右旋转,而后再绕根执行一次左旋转(右-左旋转)。若是不平衡是由根的左子结点的右子树中的长路径引起,则执行(左-右旋转)调试
显然红黑树的平衡性能比AVL的略差些,可是通过大量试验证实,实际上红黑树的效率仍是很不错了,仍能达到O(logN)code
结点的兄弟结点为黑色,同时兄弟结点的右子结点为红色,左子结点为红色;
删除操做中真正被删除的一定是只有一个红色孩子或没有孩子的结点。
若是真正的删除点是一个红色结点,那么它一定是一个叶子结点。
在完成pp11.3的时候,一切都很顺利,可是在测试的时候报错了,而后不断追溯,发现是二叉查找树继承的以前的二叉树的tostring方法有问题,这就很是难受了,又乱七八糟改了半天才能够
没有测试
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | |
---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 |
第一周 | 0/0 | 1/1 | 8/8 |
第二周 | 671/671 | 1/2 | 17/25 |
第三周 | 345/1016 | 1/3 | 15/40 |
第四周 | 405/1421 | 2/5 | 23/63 |
第五周 | 1202/2623 | 1/5 | 20/83 |
第六周 | 1741/4364 | 1/6 | 20/103 |
第七周 | 400/4764 | 1/7 | 20/123 |