• AVL Tree Insertion


    Overview

    AVL tree is a special binary search tree, by definition, any node, its left tree height and right tree height difference is not more than 1. The purpose of AVL tree is to try best to reduce the search time complexity. if the binary search tree is too deep, that will increase the search cost. By converting it to AVL, the search time can be stably controlled within O(LogN).

    Data Structure and High Level API

     public class AVLTreeNode
        {
            public int data
            {
                get;
                set;
            }
    
            public AVLTreeNode leftChild
            {
                get;
                set;
            }
    
            public AVLTreeNode rightChild
            {
                get;
                set;
            }
    
            public int height
            {
                get;
                set;
            }
    
            public AVLTreeNode(int data)
            {
                this.data = data;
                this.height = 1;
            }
        }

    AVLTreeNode Insert(AVLTreeNode node, int key)

    Recursion 

    INParam: current root node, incoming key
    OUT:       the new root node
    AVLNode Insert(AVLTreeNode node, int key)
            = 
                    1) if node is null, return new AVLNode(key)
                    2) if key is greater than current node, node.rightChild = Insert(node.rightChild, key)
                    3) if key is smaller than current node, node.leftChild = Insert(node.leftChild, key)

    Source Code

       public class AVLTree
        {
            public AVLTreeNode root
            {
                get;
                set;
            }
    
            private int Height(AVLTreeNode node)
            {
                if (node == null)
                {
                    return 0;
                }
    
                if (node.leftChild == null && node.rightChild == null)
                {
                    return 1;
                }
                else if (node.leftChild == null)
                {
                    return 1 + node.rightChild.height;
                }
                else if (node.rightChild == null)
                {
                    return 1 + node.leftChild.height;
                }
    
                return 1 + Math.Max(node.leftChild.height, node.rightChild.height);
            }
    
            private int GetBalance(AVLTreeNode node)
            {
                if (node == null)
                {
                    return 0;
                }
    
                return Height(node.leftChild) - Height(node.rightChild);
            }
          // 右旋,左孩子和右孙子
            private AVLTreeNode RightRotation(AVLTreeNode node)
            {
                AVLTreeNode childNode = node.leftChild;
                AVLTreeNode grandChildNode = childNode.rightChild;
                childNode.rightChild = node;
                node.leftChild = grandChildNode;
    
                // for affected nodes, update their height
                node.height = Math.Max(Height(node.leftChild), Height(node.rightChild)) + 1;
                childNode.height = Math.Max(Height(childNode.rightChild), Height(childNode.leftChild)) + 1;
    
                return childNode;
            }
    
        // 左旋
        // 右孩子和左孙子
    private AVLTreeNode LeftRotation(AVLTreeNode node) { AVLTreeNode childNode = node.rightChild; AVLTreeNode grandChildNode = childNode.leftChild; childNode.leftChild = node; node.rightChild = grandChildNode; node.height = Math.Max(Height(node.leftChild), Height(node.rightChild)) + 1; childNode.height = Math.Max(Height(childNode.rightChild), Height(childNode.leftChild)) + 1; return childNode; } public AVLTreeNode Insert(AVLTreeNode node, int key) { if (node == null) { return new AVLTreeNode(key); } if (key < node.data) { node.leftChild = Insert(node.leftChild, key); } else { node.rightChild = Insert(node.rightChild, key); } node.height = 1 + Math.Max(Height(node.leftChild), Height(node.rightChild)); // after insertion, calculate the balance int balance = GetBalance(node); // left left case if (balance > 1 && node.leftChild.data > key) // balance is greater than 1, which means node must have left child. { // right rotation return RightRotation(node); // 向右转, 左左组合,入参是当前根节点, 要动谁,谁就是参数 } // left right case
            6
    /
    4

            5
    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); // 右旋,传入参数是node rightChild // left rotation return LeftRotation(node); } return node; } public void InOrder(AVLTreeNode node) { if (node == null) { return; } InOrder(node.leftChild); Console.WriteLine(node.data); InOrder(node.rightChild); } }

     左旋和右旋分别cover两种情况,举个例子,右旋既可以解决左左的旋转,也可以解决右侧子树, 右左的情况。所以旋转函数只有两个API,左旋和右旋,no more choice!

  • 相关阅读:
    VMware安装CentOS6.8
    YouZack英语学习网站,英语四六级的福音
    WIN7环境下配置vscode c++环境
    连续出现的字符
    丛林中的路
    兔子与樱花
    C++语言基础--02_运算符
    C++语言基础--01_合法标识符与基本数据类型
    C++语言基础--0_前言
    字符串笔试题
  • 原文地址:https://www.cnblogs.com/xuyanran/p/8454750.html
Copyright © 2020-2023  润新知