代码改变世界

平衡二叉树(AVL)实现(1)

2010-10-08 17:06  Clingingboy  阅读(1144)  评论(0编辑  收藏  举报

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;
}

至此添加的操作全部完毕

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