1.1 二叉搜索树的插入
二叉搜索树的概念相信大家都很清楚,无非就是左小右大
创建二叉搜索树,其实就是多次调用二叉搜索树的插入方法,所以首先我们来讲讲如何插入节点到二叉搜索树里,假设一颗二叉搜索树如下,现在要插入值为4这个节点,于是我们应该要与二叉树中每一个节点比较大小,然后决定到左,右哪一个子树里去,首先比较根节点,于是应该去根节点的左子树里寻找合适的位置,然后再与5这个节点比较,于是应该去5这个节点的左子树里寻找合适的位置,再与3比较,再到3的右子树里去,但3的右子树是空(null),所以这就是我们要找的位置,此时把4插进去。通过这个我们也能得到一个结论,我们找到的插入节点的位置肯定是null,也就是不会抢占其他节点的位置。
1.2 java代码实现:
首先我们定义一个二叉搜索树类:
public class AVLTree {private AVLTree left;//指向当前节点的左儿子private AVLTree right;//指向当前节点的右儿子int Data;//节点的值域为整型public AVLTree(int Data){this.Data=Data;}
插入节点代码实现
public static AVLTree InsertNode(AVLTree root,int Data){if(root==null){//当前位置是null表示找到合适位置了AVLTree node = new AVLTree(Data);root = node;}else {if (Data > root.Data) {root.right = InsertNode(root.right, Data);} else if (Data <= root.Data) {root.left = InsertNode(root.left, Data);}}return root;}
这里采用的是递归实现,之前说过找到插入节点的位置肯定是null,于是才会有if(root==null)这个判断条件,这里之所以写成root.left/right = InsertNode(…),是因为我们要兼顾if(root=null)里的语句,这里面的语句其实就是创建一个新节点对象,赋予我们传入的值,也就是插入的节点,想一想如果没有root.left/right = InsertNode(…),我们创建的节点位置是找到了,但是并不知道谁是它的父母,于是我们需要在上一次递归的时候记下它的父母是谁。
2.1 二叉搜索树的删除
删除主要是分为三种情况,第一种,删除的节点是叶子节点,第二种,删除的节点有一个左儿子或者右儿子,第三种,删除的节点有左儿子和右儿子两个节点
什么时候,我们删除节点后需要找一个背锅侠来顶位?
如果删除的节点属于第三种情况时,我们就需要找个背锅侠来顶位,我们可以选择找出当前删除节点的左子树中最大的一个节点或者右子树中最小的一个节点来顶位,设当前删除节点是nowN,它的左子树中最大的节点是Maxleft,那么肯定满足:
nowN左子树<Maxleft<nowN<nowN右子树,满足左小右大,所以找它来顶锅准没错。
那么有聪明的朋友肯定会问了,如果背锅侠从原来位置移动到背锅位置的话,那它原来的位置怎么办,又要另一个背锅侠来顶替这个背锅侠吗,其实是不需要的,因为Maxleft肯定不会再属于第三种,它只会属于第一种或第二种情况,因为它既然是左子树最大的,那它肯定不会有右儿子,不然右儿子就是左子树里最大的,所以它可能有左儿子或者没有左儿子,也就对应了第一种情况和第二种情况,如果删除的节点是第二种情况或者背锅侠属于第二种情况,那么直接把这个节点的儿子被其祖父指向即可,我们要如何存储它的祖父呢,与上面一样用node.right/left=递归方法()即可。
**
2.2 java代码实现
**
public static AVLTree Delete(AVLTree node,int Data){if(node==null){return null; //未找到}//先找到要删除的节点if(Data>node.Data){node.right = Delete(node.right,Data);}elseif(Data<node.Data){node.left = Delete(node.left,Data);}else{//找到了,并且是属于第三种情况,要找背锅侠if(node.left!=null && node.right!=null){node.Data=findInsteadNode(node.left);//找出背锅侠来背锅Delete(node.left,Data);//找出背锅侠的原有位置}else{//背锅侠的位置 或者 是删除的节点(第一或第二种情况)if(node.right!=null)node=node.right;elseif(node.left!=null)node=node.left;elsenode=null;}}return node;}public static int findInsteadNode(AVLTree node){if(node.right!=null)return findInsteadNode(node.right);elsereturn node.Data;}