关于平衡二叉树,我查阅了一下资料,在删除部分的实现,目前还不是很完善。
于是我自己动手写了一个递归删除,每一部分都做了注释,可以把代码直接拷贝到环境中进行测试。
测试代码:
- public class TestAVLTree {
- public static void main(String[] args) {
- AVLTree<Integer> tree = new AVLTree<>();
- tree.insert(6);
- tree.insert(4);
- tree.insert(8);
- tree.insert(2);
- tree.inOrder(tree.getRoot());
- //测试删除
- tree.delete(6);
- tree.inOrder(tree.getRoot());
- }
- }
完整Tree源码如下:
- package myTree;
- import myTree.BSTree.MyTreeNode;
- public class AVLTree<T extends Comparable<? super T>> {
- private AVLNode<T> root;
- public AVLNode<T> getRoot() {
- return root;
- }
- public AVLTree(){
- this.root = null;
- }
- //插入结点
- public void insert(T x){
- root = insert(x,root);
- }
- //删除结点
- public void delete(T x){
- root = delete(x,root);
- }
- /**
- * 遍历
- * @param rootNode
- */
- public void preOrder(AVLNode<T> node){
- if(node == null)
- return ;
- System.out.println(node.element);
- preOrder(node.left);
- preOrder(node.right);
- }
- public void inOrder(AVLNode<T> node){
- if(node == null)
- return ;
- inOrder(node.left);
- System.out.println(node.element);
- inOrder(node.right);
- }
- public void postOrder(AVLNode<T> node){
- if(node == null)
- return ;
- postOrder(node.left);
- postOrder(node.right);
- System.out.println(node.element);
- }
- //私有的删除结点方法,返回root根节点
- private AVLNode<T> delete(T x, AVLNode<T> node) {
- AVLNode<T> returnNode = node;
- //找到最后也没找到要删除的结点,返回null
- if(node == null){
- return null;
- }
- //如果相等,找到待删除结点
- if(x.compareTo(node.element) == 0){
- //是叶子结点,直接返回空即可
- if(node.left == null && node.right == null){
- returnNode = null;
- }
- //如果只有一棵子树
- else if(node.left == null){
- returnNode = node.right;
- }
- else if(node.right == null){
- returnNode = node.left;
- }
- //如果有两棵子树
- else{
- //平衡度为0或1,找中序前继结点
- if(getNodeHeight(node) == 1 || (getNodeHeight(node.left)> getNodeHeight(node.right))){
- AVLNode<T> direnctPreNode = getDirectPreNode(node);
- //交换值
- node.element = direnctPreNode.element;
- returnNode = node;
- }
- //平衡度为-1时,找中序后继结点
- else{
- AVLNode<T> direnctPostNode = getDirectPostNode(node);
- //交换值
- node.element = direnctPostNode.element;
- returnNode = node;
- }
- }
- }
- //待找结点比当前结点大,继续往右找
- else if(x.compareTo(node.element)>0){
- node.right = delete(x,node.right);
- }
- //待找结点比当前结点小,继续往左找
- else{
- node.left = delete(x,node.left);
- }
- //如果returnNode为空,即删除的是叶子结点,就不需要计算高度了,直接返回即可
- if(returnNode != null){
- //删除以后判断是否是平衡树
- //左边多
- if(height(returnNode.left)-height(returnNode.right) == 2){
- //LL型
- if(returnNode.left.left != null){
- returnNode = rotateWithLeftChild(returnNode);
- }
- //LR型
- else{
- returnNode = doubleWithLeftChild(returnNode);
- }
- }
- //右边多
- else if(height(returnNode.right)- height(returnNode.left) == 2){
- //RR型
- if(returnNode.right.right !=null){
- returnNode = rotateWithRightChild(returnNode);
- }
- //RL型
- else{
- returnNode = doubleWithRightChild(returnNode);
- }
- }
- //重新计算一下当前结点的height并返回该结点
- returnNode.height = Math.max(height(returnNode.left), height(returnNode.right))+1;
- }
- return returnNode;
- }
- //得到中序后继结点
- private AVLNode<T> getDirectPostNode(AVLNode<T> delNode){
- AVLNode<T> parentNode = delNode;
- AVLNode<T> diRectPostNode = delNode;
- AVLNode<T> currentNode = delNode.right;
- while(currentNode != null){
- parentNode = diRectPostNode;
- diRectPostNode = currentNode;
- currentNode = currentNode.left;
- }
- //如果后继结点是待删除结点的右孩,删除结点
- if(parentNode == delNode){
- parentNode.right = diRectPostNode.right;
- }
- //如果不是,删除结点
- else{
- parentNode.left = diRectPostNode.right;
- diRectPostNode.right = null;
- }
- return diRectPostNode;
- }
- //得到中序前继结点
- private AVLNode<T> getDirectPreNode(AVLNode<T> delNode){
- AVLNode<T> parentNode = delNode;
- AVLNode<T> diRectPostNode = delNode;
- AVLNode<T> currentNode = delNode.left;
- while(currentNode != null){
- parentNode = diRectPostNode;
- diRectPostNode = currentNode;
- currentNode = currentNode.right;
- }
- //如果后继结点是待删除结点的右孩,删除结点
- if(parentNode == delNode){
- parentNode.left = diRectPostNode.left;
- }
- //如果不是,删除结点
- else{
- parentNode.right = diRectPostNode.left;
- diRectPostNode.left = null;
- }
- return diRectPostNode;
- }
- //得到结点的height方法
- private int getNodeHeight(AVLNode<T> node){
- return Math.max(height(node.left), height(node.right))+1;
- }
- //私有的插入结点方法,返回root
- private AVLNode<T> insert(T x, AVLNode<T> root) {
- if(root == null)
- return new AVLNode<T>(x,null,null);
- int compareResult = x.compareTo(root.element);
- if(compareResult<0){
- root.left = insert(x,root.left);
- //打破平衡
- if(height(root.left)-height(root.right) == 2){
- //LL型
- if(x.compareTo(root.left.element)<0)
- root = rotateWithLeftChild(root);
- //LR型
- else
- root = doubleWithLeftChild(root);
- }
- }
- else if(compareResult >0){
- root.right = insert(x,root.right);
- if(height(root.right)- height(root.left) == 2){
- //RR型
- if(x.compareTo(root.right.element)>0)
- root = rotateWithRightChild(root);
- else
- root = doubleWithRightChild(root);
- }
- }
- else{
- ;
- }
- root.height = Math.max(height(root.left), height(root.right))+1;
- return root;
- }
- private AVLTree<T>.AVLNode<T> doubleWithRightChild(AVLTree<T>.AVLNode<T> root) {
- root.right = rotateWithLeftChild(root.right);
- return rotateWithRightChild(root);
- }
- private AVLTree<T>.AVLNode<T> rotateWithRightChild(AVLTree<T>.AVLNode<T> root) {
- AVLNode<T> k = root.right;
- root.right = k.left;
- k.left = root;
- root.height = Math.max(height(root.left), height(root.right))+1;
- k.height = Math.max(height(k.left), height(k.right))+1;
- return k;
- }
- private AVLTree<T>.AVLNode<T> doubleWithLeftChild(AVLTree<T>.AVLNode<T> root) {
- root.left = rotateWithRightChild(root.left);
- return rotateWithLeftChild(root);
- }
- private AVLTree<T>.AVLNode<T> rotateWithLeftChild(AVLTree<T>.AVLNode<T> root) {
- AVLNode<T> k = root.left;
- root.left = k.right;
- k.right = root;
- root.height = Math.max(height(root.left), height(root.right))+1;
- k.height = Math.max(height(k.left), height(k.right))+1;
- return k;
- }
- private int height(AVLNode<T> n) {
- return n == null ? -1:n.height;
- }
- class AVLNode<T> {
- T element;//结点中的数据
- AVLNode<T> left;//左孩
- AVLNode<T> right;//右孩
- int height;//结点高度
- AVLNode(T element){
- this.element = element;
- }
- AVLNode(T element,AVLNode<T> lt,AVLNode<T> rt){
- this.element = element;
- this.left = lt;
- this.right = rt;
- this.height = 0;
- }
- }
- }