济南网站建设wuliankj,电脑网页传奇,注册网址,网站建设培训学院一、二叉搜索树
1. 概念
二叉搜索树又称二叉排序树#xff0c;它或者是一棵空树#xff0c;或者是具有以下性质的二叉树#xff1a;
若它的左子树不为空#xff0c;则左子树上所有节点的值都小于根节点的值若它的右子树不为空#xff0c;则右子树上所有节点的值都大于根…一、二叉搜索树
1. 概念
二叉搜索树又称二叉排序树它或者是一棵空树或者是具有以下性质的二叉树
若它的左子树不为空则左子树上所有节点的值都小于根节点的值若它的右子树不为空则右子树上所有节点的值都大于根节点的值它的左右子树也分别为二叉搜索树 int[] array {5,3,4,1,7,8,2,6,0,9};
2. 查找 3. 插入
1. 如果树为空树即根 null直接插入 2. 如果树不是空树按照查找逻辑确定插入位置插入新结点 4. 删除
设待删除结点为 cur待删除结点的双亲结点为 parent 。
1. cur.left null
cur 是 root则 root cur.rightcur 不是 rootcur 是 parent.left则 parent.left cur.rightcur 不是 rootcur 是 parent.right则 parent.right cur.right
2. cur.right null
cur 是 root则 root cur.left cur 不是 rootcur 是 parent.left则 parent.left cur.leftcur 不是 rootcur 是 parent.right则 parent.right cur.left
3. cur.left ! null cur.right ! null
需要使用替换法进行删除即在 cur 的右子树中寻找中序遍历的下一个结点 temp (也就是cur右子树中最左下的节点) 以及该节点的前驱 pre用 temp 的值填补到被删除节点 cur 中即cur.val temp.val; 再来处理 temp 结点的删除问题。注意最终找到的 temp 节点的值一定是 cur 的右子树中值最小的且一定有 temp.left null。当 temp 节点就是 cur.right 时此时一定是 tpre cur则让 tpre.right temp.right; 当 temp 节点是 cur.right然后再一直往左走时直到走到最左端则让 tpre.left temp.right 。
5. 代码实现
public class BinarySearchTree {public class TreeNode{public TreeNode left;public TreeNode right;public int val;public TreeNode(int val) {this.val val;}}public TreeNode root null;//查找public TreeNode search(int key){if(root null){return null;}TreeNode cur root;while (cur ! null){if (cur.val key){cur cur.left;}else if(cur.val key){cur cur.right;}else {return cur;}}return null;}//插入public boolean insert(int key){TreeNode node new TreeNode(key);if(root null){root node;return true;}TreeNode prev,cur;prev root;cur root;while (cur ! null){if(cur.val key){prev cur;cur cur.left;}else if(cur.val key){prev cur;cur cur.right;}else {return false;}}if(prev.val key){prev.left node;}else {prev.right node;}return true;}//删除public boolean remove(int key){TreeNode cur root;TreeNode parent root;while (cur ! null){if (cur.val key){parent cur;cur cur.left;}else if(cur.val key){parent cur;cur cur.right;}else {removeNode(parent,cur);return true;}}return false ;}private void removeNode(TreeNode parent, TreeNode cur){if(cur.left null){ // cur左右孩子都为null的情况也会默认在次处理。if(cur root){root root.right;}else if(parent.left cur){parent.left cur.right;}else{parent.right cur.right;}}else if(cur.right null){if(cur root){root root.left;}else if(parent.left cur){parent.left cur.left;}else{parent.right cur.left;}}else { // 左右孩子都不为null。if (cur root){root null;}// 用temp找到cur右子树中最左下的节点。// 两种情况1.当cur.right没有左子树时cur右子树中最左下的节点是cur.right;// 2.当cur.right有左子树时,cur右子树中最左下的节点是cur.right, 然后一直往左走。TreeNode temp cur.right;TreeNode tprev cur;while (temp.left ! null){tprev temp;temp temp.left;}cur.val temp.val;if(tprev.left temp){tprev.left temp.right;}else{tprev.right temp.right;}}}//中序遍历public void inOrder(TreeNode root){if (root null){return;}inOrder(root.left);System.out.print(root.val );inOrder(root.right);}
}
6. 性能分析
插入和删除操作都必须先查找查找效率代表了二叉搜索树中各个操作的性能。对有n个结点的二叉搜索树若每个元素查找的概率相等则二叉搜索树平均查找长度是结点在二叉搜索树的深度 的函数即结点越深则比较次数越多。 但对于同一个关键码集合如果各关键码插入的次序不同可能得到不同结构的二叉搜索树 最优情况下二叉搜索树为完全二叉树其平均比较次数为
最差情况下二叉搜索树退化为单支树其平均比较次数为
问题如果退化成单支树二叉搜索树的性能就失去了。那能否进行改进不论按照什么次序插入关键码都可以是二叉搜索树的性能最佳
答为了避免树的高度增长过快降低二叉排序树的性能规定在插入和删除结点时要保证任意结点的左、右子树高度差的绝对值不超过1将这样的二叉树称为平衡二叉树(BalancedBinary Tree)也称 AVL树。定义结点左子树与右子树的高度差为该结点的平衡因子则平衡二叉树结点的平衡因子的值只可能是-1、0或1。
7. 平衡二叉树
7.1 定义
平衡二叉树可定义为或是一棵空树或是具有下列性质的二叉树它的左子树和右子树都是平衡二叉树且左子树和右子树的高度差的绝对值不超过 1。 7.2 调整
平衡二叉树的调整。
8. 和 Java 类集的关系
TreeMap 和 TreeSet 即 Java 中利用搜索树实现的 Map 和 Set实际上用的是红黑树而红黑树是一棵近似平衡的二叉搜索树即在二叉搜索树的基础之上 颜色以及红黑树性质验证。
二、搜索
1. 概念及场景