zoukankan      html  css  js  c++  java
  • AVL Tree Deletion

    Overview


     知识点:

    1. delete函数的signature

    public AVLTreeNode Delete(AVLTreeNode node, int key)

    2. 算法,如何删除节点:
              // 如果左右节点都为空,node = null
              // 如果一个为空,另一个字节点不为空,把node节点替换成不为空的字节点
              // 如果两个节点都不为空,则要找到中序后继节点,然后去其值,再递归删掉右侧子树的后继节点

    3. 旋转:

     左旋和右旋逻辑和插入是一致的。

    Source Code


            private int GetMinValue(AVLTreeNode node)
            {
                if (node == null)
                {
                    throw new Exception("node is null.");
                }
    
                if (node.rightChild != null)
                {
                    AVLTreeNode temp = node.rightChild;
                    while (temp.leftChild != null)
                    {
                        temp = temp.leftChild;
                    }
              // don't write it like temp.leftChild.data
                    return temp.data;
                }
                else
                {
                    throw new Exception("successor node is not found");
                }
            }
    
            public AVLTreeNode Delete(AVLTreeNode node, int key)
            {
                // STEP 1: standard BST deletion
                if (node == null)
                {
                    return node;
                }
    
                if (key < node.data)
                {
                    node.leftChild = Delete(node.leftChild, key);
                }
                else if (key > node.data)
                {
                    node.rightChild = Delete(node.rightChild, key);
                }
                else
                {
              // 如果左右节点都为空,node = null
              // 如果一个为空,另一个字节点不为空,把node节点替换成不为空的字节点
              // 如果两个节点都不为空,则要找到中序后继节点,然后去其值,再递归删掉右侧子树的后继节点
    if (node.leftChild == null || node.rightChild == null) { AVLTreeNode temp = null; if (node.leftChild == null) { temp = node.rightChild; } else { temp = node.leftChild; } if (temp == null) { // no child at all node = null; } // has one child else { node = temp; } } else { // has two children node.data = GetMinValue(node); node.rightChild = Delete(node.rightChild, node.data); } } // 下面这个逻辑很重要,如果node是叶子节点,直接返回,没有必要继续下去 if (node == null) { return node; } // STEP 2: update height, 下面逻辑和插入是一样的 node.height = 1 + Math.Max(Height(node.leftChild), Height(node.rightChild)); // STEP 3: calculate balance factor // after insertion, calculate the balance int balance = GetBalance(node); // left left case if (balance > 1 && node.leftChild.data > key) { // right rotation return RightRotation(node); } // left right case if (balance > 1 && node.leftChild.data <= key) { // left rotation first node.leftChild = LeftRotation(node.leftChild); // then do right rotation return RightRotation(node); } // right right case if (balance < -1 && node.rightChild.data <= key) { // left rotation return LeftRotation(node); } // right left case if (balance < -1 && node.rightChild.data > key) { // right rotation node.rightChild = RightRotation(node.rightChild); // left rotation return LeftRotation(node); } return node; }
  • 相关阅读:
    20款时尚的 WordPress 企业模板【免费主题下载】
    3D Grid Effect – 使用 CSS3 制作网格动画效果
    WTF Forms – 使用 CSS 实现用户体验更好的表单
    Tiff – 值得你体验一下的可视化的字体对比工具
    Quill – 可以灵活自定义的开源的富文本编辑器
    Photopile JS – 帮助你实现精致的照片堆叠效果
    Web 前端开发人员和设计师必读精华文章【系列二十六】
    Shepherd – 在应用程序中轻松实现引导功能
    Gulp.js
    12款响应式的 jQuery 旋转木马(传送带)插件
  • 原文地址:https://www.cnblogs.com/xuyanran/p/8471325.html
Copyright © 2011-2022 走看看