平衡二叉树的删除实现---递归

关于平衡二叉树,我查阅了一下资料,在删除部分的实现,目前还不是很完善。

于是我自己动手写了一个递归删除,每一部分都做了注释,可以把代码直接拷贝到环境中进行测试。


测试代码:

  1. public class TestAVLTree {  
  2.     public static void main(String[] args) {  
  3.         AVLTree<Integer> tree = new AVLTree<>();  
  4.         tree.insert(6);  
  5.         tree.insert(4);  
  6.         tree.insert(8);  
  7.         tree.insert(2);  
  8.         tree.inOrder(tree.getRoot());  
  9.           
  10.         //测试删除  
  11.         tree.delete(6);  
  12.         tree.inOrder(tree.getRoot());  
  13.     }  
  14.   


完整Tree源码如下:

  1. package myTree;  
  2.   
  3.   
  4. import myTree.BSTree.MyTreeNode;  
  5.   
  6.   
  7. public class AVLTree<T extends Comparable<? super T>> {  
  8.   
  9.   
  10.     private AVLNode<T> root;  
  11.       
  12.       
  13.       
  14.     public AVLNode<T> getRoot() {  
  15.         return root;  
  16.     }  
  17.   
  18.   
  19.     public AVLTree(){  
  20.         this.root = null;  
  21.     }  
  22.       
  23.     //插入结点  
  24.     public void insert(T x){  
  25.         root = insert(x,root);  
  26.     }  
  27.       
  28.     //删除结点  
  29.     public void delete(T x){  
  30.         root = delete(x,root);  
  31.     }  
  32.       
  33.     /** 
  34.      * 遍历 
  35.      * @param rootNode 
  36.      */  
  37.     public void preOrder(AVLNode<T> node){  
  38.         if(node == null)  
  39.             return ;  
  40.         System.out.println(node.element);  
  41.         preOrder(node.left);  
  42.         preOrder(node.right);  
  43.           
  44.     }  
  45.       
  46.     public void inOrder(AVLNode<T> node){  
  47.         if(node == null)  
  48.             return ;  
  49.         inOrder(node.left);  
  50.         System.out.println(node.element);  
  51.         inOrder(node.right);  
  52.     }  
  53.       
  54.     public void postOrder(AVLNode<T> node){  
  55.         if(node == null)  
  56.             return ;  
  57.         postOrder(node.left);  
  58.         postOrder(node.right);  
  59.         System.out.println(node.element);  
  60.     }  
  61.       
  62.     //私有的删除结点方法,返回root根节点  
  63.     private AVLNode<T> delete(T x, AVLNode<T> node) {  
  64.         AVLNode<T> returnNode = node;  
  65.         //找到最后也没找到要删除的结点,返回null  
  66.         if(node == null){  
  67.             return null;  
  68.         }  
  69.         //如果相等,找到待删除结点  
  70.         if(x.compareTo(node.element) == 0){  
  71.             //是叶子结点,直接返回空即可  
  72.             if(node.left == null && node.right == null){  
  73.                 returnNode = null;  
  74.             }  
  75.             //如果只有一棵子树  
  76.             else if(node.left == null){  
  77.                 returnNode = node.right;  
  78.             }  
  79.             else if(node.right == null){  
  80.                 returnNode = node.left;  
  81.             }  
  82.             //如果有两棵子树  
  83.             else{  
  84.                 //平衡度为0或1,找中序前继结点  
  85.                 if(getNodeHeight(node) == 1 || (getNodeHeight(node.left)> getNodeHeight(node.right))){  
  86.                     AVLNode<T> direnctPreNode = getDirectPreNode(node);  
  87.                     //交换值  
  88.                     node.element = direnctPreNode.element;  
  89.                     returnNode = node;    
  90.                 }  
  91.                 //平衡度为-1时,找中序后继结点  
  92.                 else{  
  93.                     AVLNode<T> direnctPostNode = getDirectPostNode(node);  
  94.                     //交换值  
  95.                     node.element = direnctPostNode.element;  
  96.                     returnNode = node;    
  97.                 }  
  98.             }  
  99.         }  
  100.         //待找结点比当前结点大,继续往右找  
  101.         else if(x.compareTo(node.element)>0){  
  102.             node.right = delete(x,node.right);  
  103.         }  
  104.         //待找结点比当前结点小,继续往左找  
  105.         else{  
  106.             node.left = delete(x,node.left);  
  107.         }  
  108.           
  109.         //如果returnNode为空,即删除的是叶子结点,就不需要计算高度了,直接返回即可  
  110.         if(returnNode != null){  
  111.             //删除以后判断是否是平衡树  
  112.             //左边多  
  113.             if(height(returnNode.left)-height(returnNode.right) == 2){  
  114.                 //LL型  
  115.                 if(returnNode.left.left != null){  
  116.                     returnNode = rotateWithLeftChild(returnNode);  
  117.                 }  
  118.                 //LR型  
  119.                 else{  
  120.                     returnNode = doubleWithLeftChild(returnNode);  
  121.                 }  
  122.             }  
  123.             //右边多  
  124.             else if(height(returnNode.right)- height(returnNode.left) == 2){  
  125.                 //RR型  
  126.                 if(returnNode.right.right !=null){  
  127.                     returnNode = rotateWithRightChild(returnNode);  
  128.                 }  
  129.                 //RL型  
  130.                 else{  
  131.                     returnNode = doubleWithRightChild(returnNode);  
  132.                 }  
  133.             }  
  134.             //重新计算一下当前结点的height并返回该结点  
  135.             returnNode.height = Math.max(height(returnNode.left), height(returnNode.right))+1;  
  136.         }  
  137.         return returnNode;  
  138.           
  139.     }  
  140.   
  141.   
  142.     //得到中序后继结点  
  143.     private AVLNode<T> getDirectPostNode(AVLNode<T> delNode){  
  144.         AVLNode<T> parentNode = delNode;  
  145.         AVLNode<T> diRectPostNode = delNode;  
  146.         AVLNode<T> currentNode = delNode.right;  
  147.         while(currentNode != null){  
  148.             parentNode = diRectPostNode;  
  149.             diRectPostNode = currentNode;  
  150.             currentNode = currentNode.left;  
  151.         }  
  152.         //如果后继结点是待删除结点的右孩,删除结点  
  153.         if(parentNode == delNode){  
  154.             parentNode.right = diRectPostNode.right;  
  155.         }  
  156.         //如果不是,删除结点  
  157.         else{  
  158.             parentNode.left = diRectPostNode.right;  
  159.             diRectPostNode.right = null;  
  160.         }  
  161.         return diRectPostNode;  
  162.           
  163.     }  
  164.       
  165.     //得到中序前继结点  
  166.     private AVLNode<T> getDirectPreNode(AVLNode<T> delNode){  
  167.         AVLNode<T> parentNode = delNode;  
  168.         AVLNode<T> diRectPostNode = delNode;  
  169.         AVLNode<T> currentNode = delNode.left;  
  170.         while(currentNode != null){  
  171.             parentNode = diRectPostNode;  
  172.             diRectPostNode = currentNode;  
  173.             currentNode = currentNode.right;  
  174.         }  
  175.         //如果后继结点是待删除结点的右孩,删除结点  
  176.         if(parentNode == delNode){  
  177.             parentNode.left = diRectPostNode.left;  
  178.         }  
  179.         //如果不是,删除结点  
  180.         else{  
  181.             parentNode.right = diRectPostNode.left;  
  182.             diRectPostNode.left = null;  
  183.         }  
  184.         return diRectPostNode;  
  185.     }  
  186.       
  187.       
  188.       
  189.     //得到结点的height方法  
  190.     private int getNodeHeight(AVLNode<T> node){  
  191.         return Math.max(height(node.left), height(node.right))+1;  
  192.     }  
  193.       
  194.       
  195.     //私有的插入结点方法,返回root  
  196.     private AVLNode<T> insert(T x, AVLNode<T> root) {  
  197.         if(root == null)  
  198.             return new AVLNode<T>(x,null,null);  
  199.           
  200.         int compareResult = x.compareTo(root.element);  
  201.           
  202.         if(compareResult<0){  
  203.             root.left = insert(x,root.left);  
  204.             //打破平衡  
  205.             if(height(root.left)-height(root.right) == 2){  
  206.                 //LL型  
  207.                 if(x.compareTo(root.left.element)<0)  
  208.                     root = rotateWithLeftChild(root);  
  209.                 //LR型  
  210.                 else  
  211.                     root = doubleWithLeftChild(root);  
  212.             }  
  213.         }  
  214.         else if(compareResult >0){  
  215.             root.right = insert(x,root.right);  
  216.             if(height(root.right)- height(root.left) == 2){  
  217.                 //RR型  
  218.                 if(x.compareTo(root.right.element)>0)  
  219.                     root = rotateWithRightChild(root);  
  220.                 else  
  221.                     root = doubleWithRightChild(root);  
  222.             }  
  223.         }  
  224.         else{  
  225.             ;  
  226.         }  
  227.         root.height = Math.max(height(root.left), height(root.right))+1;  
  228.         return root;  
  229.           
  230.     }  
  231.   
  232.   
  233.       
  234.       
  235.       
  236.   
  237.   
  238.     private AVLTree<T>.AVLNode<T> doubleWithRightChild(AVLTree<T>.AVLNode<T> root) {  
  239.         root.right = rotateWithLeftChild(root.right);  
  240.         return rotateWithRightChild(root);  
  241.     }  
  242.   
  243.   
  244.     private AVLTree<T>.AVLNode<T> rotateWithRightChild(AVLTree<T>.AVLNode<T> root) {  
  245.         AVLNode<T> k = root.right;  
  246.         root.right = k.left;  
  247.         k.left = root;  
  248.         root.height = Math.max(height(root.left), height(root.right))+1;  
  249.         k.height = Math.max(height(k.left), height(k.right))+1;  
  250.         return k;  
  251.     }  
  252.   
  253.   
  254.     private AVLTree<T>.AVLNode<T> doubleWithLeftChild(AVLTree<T>.AVLNode<T> root) {  
  255.         root.left = rotateWithRightChild(root.left);  
  256.         return rotateWithLeftChild(root);  
  257.     }  
  258.   
  259.   
  260.     private AVLTree<T>.AVLNode<T> rotateWithLeftChild(AVLTree<T>.AVLNode<T> root) {  
  261.         AVLNode<T> k = root.left;  
  262.         root.left = k.right;  
  263.         k.right = root;  
  264.         root.height = Math.max(height(root.left), height(root.right))+1;  
  265.         k.height = Math.max(height(k.left), height(k.right))+1;  
  266.         return k;  
  267.           
  268.     }  
  269.   
  270.   
  271.     private int height(AVLNode<T> n) {  
  272.         return n == null ? -1:n.height;  
  273.     }  
  274.   
  275.   
  276.   
  277.   
  278.       
  279.   
  280.   
  281.   
  282.   
  283.     class AVLNode<T> {  
  284.         T element;//结点中的数据  
  285.         AVLNode<T> left;//左孩  
  286.         AVLNode<T> right;//右孩  
  287.         int height;//结点高度  
  288.           
  289.         AVLNode(T element){  
  290.             this.element = element;  
  291.         }  
  292.           
  293.         AVLNode(T element,AVLNode<T> lt,AVLNode<T> rt){  
  294.             this.element = element;  
  295.             this.left = lt;  
  296.             this.right = rt;  
  297.             this.height = 0;  
  298.         }  
  299.           
  300.           
  301.     }  
  302. }  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值