zoukankan      html  css  js  c++  java
  • 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!

  • 相关阅读:
    Qt Quick 简单介绍
    Windows下ElasticSearch及相关插件的安装
    Light OJ 1317 Throwing Balls into the Baskets 概率DP
    Cocos2d-x-lua学习点滴
    JAVA网络编程--UDP通信
    ASP.NET Web API 应用教程(一) ——数据流使用
    NGUI创建Camera参数为Simple 2D的UI UI对象的结构UI Root(2D)
    端口扫描器——ZenmapKail Linux渗透测
    直接操作游戏对象C#游戏开发
    BeagleBone Black项目实训手册(大学霸内部资料)
  • 原文地址:https://www.cnblogs.com/xuyanran/p/8454750.html
Copyright © 2011-2022 走看看