zoukankan      html  css  js  c++  java
  • 平衡二叉树(AVL)实现(1)

    http://www.cnblogs.com/abatei/archive/2008/11/17/1335031.html
    修改自陈广老师

    1.Node

    public class Node 
    {
        public int Data { get; set; }
    
        //记录平衡因子 
        public int BF { get; set; }
    
        public Node Left { get; set; }
    
        public Node Right { get; set; }
    
        public Node(int val)
        {
            Data=val;
        }
    }

    2.操作,对外开放的只有添加和删除操作,并记录了一个头节点

    public interface IBinaryTree
    {
        Node Head { get; }
    
        bool Add(int value);
    
        bool Remove(int value);
    }

    3.BinarySearchTree

    public class BinarySearchTree:IBinaryTree
    {     
        private Node[] path = new Node[32]; 
        private int currentIndex; 
    
        private Node _head; 
        public Node Head             
        {
            get { return _head; }
        }
    
        public bool IsEmpty
        {
            get { return _head == null; }
        }
    
        public bool Add(int value)     {   
            return true;
        }
            public bool Remove(int value)
        {
            return false;     }
    }

    添加节点

    新增的节点默认平衡因子为0,但会影响上层节点

    1.当节点为空时,添加节点

    public bool Add(int value) {   
        
        if (IsEmpty)
        {
            _head = new Node(value);
            _head.BF = 0;
            return true;
        }
    }

    2.寻找插入点,并插入节点

    image

    如果要插入6

    1.首先6跟根节点20比较,选左节点
    2.
    然后6跟15比较,再选15的左节点
    3.
    由于12没有子节点,所以就找到了插入点(现在还不能插入).并记录该节点
    4.
    6肯定是12的子节点;6跟12比较,6比12小,所以为12的左节点

    代码实现1-3
    下面代码用prev变量 记录插入点即12

    currentIndex = 0;
    Node prev = null, current = _head;
    while (current != null)
    {
        prev = current;
        current = (value < prev.Data) ? prev.Left : prev.Right;
    }
    
    代码实现4
    下面代码先声明一个节点,然后加入到父节点中
    current = new Node(value); 
    current.BF = 0;
    if(value < prev.Data)
    { prev.Left = current; }
    else
    { prev.Right = current; }

    改变父节点路径平衡因子

    以上的操作属于二叉搜索树的操作,接下来的才是关键.

    在添加完节点后,我们还要同时变更父节点的平衡因子

    1.由于平衡因子等于节点的左节点高度-节点的右节点高度

    所以当添加的节点为左节点时,父节点平衡因子+1,反之则-1

    2.改变所有经过节点的平衡因子,所以要把这些节点记录下来,必经是一层层自下而上的父节点
    3.平衡因子是叠加的,而不是赋值的

    int bf = 0;
    while (currentIndex > 0)
    {   
    //确定节点添加的方向是左还是又
    bf = (value < path[currentIndex - 1].Data) ? 1 : -1; path[--currentIndex].BF += bf; //叠加
    bf = path[currentIndex].BF; //取当前节点平衡因子
    }

    如果平衡因子的绝对值等于2则开始旋转

    上面变更平衡因子后,接下来还要判断bf的值得,如果绝对值等于2就需要开始旋转操作.

    if (bf == 0)
    {
        return true;
    }
    else if (bf == 2 || bf == -2) {
        RotateSubTree(bf);
        return true;
    }

    至此添加的操作全部完毕

    下面将是旋转部分,分开写...

  • 相关阅读:
    搜索框用定时器限制发送请求
    vue的生命周期,钩子函数
    事件委托的实现流程
    在vscode中快速生成vue模板
    JS继承
    各种宽高
    ES6新特性
    python入门学习一
    字符编码
    npm install --save 与 npm install --save-dev 的区别
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/1845975.html
Copyright © 2011-2022 走看看