平衡树

形态匀称的二叉树称为平衡二叉树 (Balanced binary tree) ,其严格定义是:
  一棵空树是平衡二叉树;若 T 是一棵非空二叉树,其左、右子树为 TL 和 TR ,令 hl 和 hr 分别为左、右子树的深度。当且仅当
   ①TL 、 TR 都是平衡二叉树; 
   ② | hl - hr |≤ 1;
时,则 T 是平衡二叉树。
【例】如图 8.4 所示。
         
             (a)平衡二叉树           (b)非平衡二叉树
                      图8.3 平衡二叉树与非平衡二叉树
相应地定义 hl - hr 为二叉平衡树的平衡因子 (balance factor) 。因此,平衡二叉树上所有结点的平衡因子可能是 -1 , 0 , 1 。换言之,若一棵二叉树上任一结点的平衡因子的绝对值都不大于 1 ,则该树是就平衡二叉树。
动态平衡技术 
1.动态平衡技术

Adelson-Velskii 和 Landis 提出了一个动态地保持二叉排序树平衡的方法,其基本思想是:
  在构造二叉排序树的过程中,每当插入一个结点时,首先检查是否因插入而破坏了树的平衡性,如果是因插入结点而破坏了树的平衡性,则找出其中 最小不平衡子树,在保持排序树特性的前提下,调整最小不平衡子树中各结点之间的连接关系,以达到新的平衡。通常将这样得到的平衡二叉排序树简称为  AVL 树
2.最小不平衡子树
  以离插入结点最近、且平衡因子绝对值大于 1 的结点作根结点的子树。为了简化讨论,不妨假设二叉排序树的最小不平衡子树的根结点为 A ,则调整该子树的规律可归纳为下列四种情况:
(1) LL 型:
  新结点 X 插在 A 的左孩子的左子树里。调整方法见图 8.5(a) 。图中以 B 为轴心,将 A 结点从 B 的右上方转到 B 的右下侧,使 A 成为 B 的右孩子。
      
          图8.5 平衡调整的4种基本类型(结点旁的数字是平衡因子)
(2)RR 型:
  新结点 X 插在 A 的右孩子的右子树里。调整方法见图 8.5(b) 。图中以 B 为轴心,将 A 结点从 B 的左上方转到 B 的左下侧,使 A 成为 B 的左孩子。
(3)LR 型:
  新结点 X 插在 A 的左孩子的右子树里。调整方法见图 8.5(c) 。分为两步进行:第一步以 X 为轴心,将 B 从 X 的左上方转到 X 的左下侧,使 B 成为 X 的左孩子, X 成为 A 的左孩子。第二步跟 LL 型一样处理 ( 应以 X 为轴心 ) 。 
(4)RL 型:
  新结点 X 插在 A 的右孩子的左子树里。调整方法见图 8.5(d) 。分为两步进行:第一步以 X 为轴心,将 B 从 X 的右上方转到 X 的右下侧,使 B 成为 X 的右孩子, X 成为 A 的右孩子。第二步跟 RR 型一样处理 ( 应以 X 为轴心 ) 。
【例】
实际的插入情况,可能比图 8.5 要复杂。因为 A 、 B 结点可能还会有子树。现举一例说明,设一组记录的关键字按以下次序进行插入: 4 、 5 、 7 , 2 、 1 、 3 、 6 ,其生成及调整成二叉平衡树的过程示于图 8.6 。 
  在图 8.6 中,当插入关键字为 3 的结点后,由于离结点 3 最近的平衡因子为 2 的祖先是根结点 5 。所以,第一次旋转应以结点 4 为轴心,把结点 2 从结点 4 的左上方转到左下侧,从而结点 5 的左孩子是结点 4 ,结点 4 的左孩子是结点 2 ,原结点 4 的左孩子变成了结点 2 的右孩子。第二步再以结点 4 为轴心,按 LL 类型进行转换。这种插入与调整平衡的方法可以编成算法和程序,这里就不再讨论了。 

         图 8.6 二叉平衡树插入结点 ( 结点旁的数字为其平衡因子 )


代码:

template<class E, class K>   
class AVLtree    
{   
public:   
    AVLtree() {root = 0;}   
    ~AVLtree() {Erase(root);}   
    bool Search(const K& k, E& e) const;   
    AVLtree<E,K>& Insert(const E& e);   
    AVLtree<E,K>& Delete(const K& k, E& e);   
    void Ascend() {InOutput(root); cout << endl;}   
    void PostOut() {PostOutput(root); cout << endl;}   
  
private:   
    AVLNode<E,K> *root;   
  
    void Erase(AVLNode<E,K> *t);   
    void InOutput(AVLNode<E,K> *t);   
    void PostOutput(AVLNode<E,K> *t);   
    void FixBF(AVLNode<E,K> *, AVLNode<E,K>*, const E&);   
    void RRrotate(AVLNode<E,K> *, AVLNode<E,K>*, AVLNode<E,K> *);   
    void LLrotate(AVLNode<E,K> *, AVLNode<E,K>*, AVLNode<E,K> *);   
    void RLrotate(AVLNode<E,K> *, AVLNode<E,K>*, AVLNode<E,K> *);   
    void LRrotate(AVLNode<E,K> *, AVLNode<E,K>*, AVLNode<E,K> *);   
};   
  
template<class E, class K>   
void AVLtree<E,K>::Erase(AVLNode<E,K> *t)   
{   
    //用前序遍历的方式删除所有节点   
    if (t)    
    {   
        Erase(t->LeftChild);   
        Erase(t->RightChild);   
        delete t;   
    }   
}   
  
template<class E, class K>   
bool AVLtree<E,K>::Search(const K& k, E &e) const  
{   
    AVLNode<E,K> *p = root;   
    while (p)   
    {   
        if (k < p->data)    
            p = p->LeftChild;   
        else if (k > p->data)    
            p = p->RightChild;   
        else    
        {   
            e = p->data;   
            return true;   
        }   
    }   
    return false;   
}   
  
template<class E, class K>   
void AVLtree<E,K>::FixBF(AVLNode<E,K> *q,   
                         AVLNode<E,K> *r, const E &e)   
{   
    //从q到r的平衡因子通常为0   
    //根据实际情况改变成 +1 或 -1   
    while (q != r)   
    {   
        if (e < q->data)    
        {   
            q->bf = 1;   
            q = q->LeftChild;   
        }   
        else    
        {   
            q->bf = -1;   
            q = q->RightChild;   
        }   
    }   
}   
  
template<class E, class K>   
void AVLtree<E,K>::LLrotate(AVLNode<E,K> *PA, AVLNode<E,K> *A, AVLNode<E,K> *B)   
{   
    //LL型的旋转   
    A->LeftChild = B->RightChild;   
    B->RightChild = A;   
    if (PA) // A 是否有父节点   
    {   
        if (A == PA->LeftChild)   
            PA->LeftChild = B;   
        else    
            PA->RightChild = B;   
    }   
    else  
    {   
        root = B;   
    }   
  
    //设置平衡因子   
    A->bf = B->bf = 0;   
}   
  
template<class E, class K>   
void AVLtree<E,K>::RRrotate(AVLNode<E,K> *PA, AVLNode<E,K> *A, AVLNode<E,K> *B)   
{   
    //RR型的旋转   
    A->RightChild = B->LeftChild;   
    B->LeftChild = A;   
    if (PA) // A 是否有父节点   
    {   
        if (A == PA->LeftChild)   
            PA->LeftChild = B;   
        else    
            PA->RightChild = B;   
    }   
    else  
    {   
        root = B;   
    }   
  
    //设置平衡因子   
    A->bf = B->bf = 0;   
}   
  
template<class E, class K>   
void AVLtree<E,K>::LRrotate(AVLNode<E,K> *PA,   
                   AVLNode<E,K> *A, AVLNode<E,K> *B)   
{   
    //LR型的旋转   
    AVLNode<E,K> *C = B->RightChild;   
  
  
    A->LeftChild = C->RightChild;   
    B->RightChild = C->LeftChild;   
    C->LeftChild = B;   
    C->RightChild = A;   
    if (PA) // A 是否有父节点   
    {   
        if (A == PA->LeftChild)   
            PA->LeftChild = C;   
        else  
            PA->RightChild = C;   
    }   
    else    
    {   
        root = C;   
    }   
  
    //设置平衡因子   
    int b = C->bf;   
    if (b == 1)    
    {   
        B->bf = 0;   
        A->bf = -1;   
    }   
    else if (b == -1)    
    {   
        B->bf = 1;   
        A->bf = 0;   
    }   
    else // b = 0   
    {   
        B->bf = A->bf = 0;   
    }   
  
    C->bf = 0;   
}   
  
template<class E, class K>   
void AVLtree<E,K>::RLrotate(AVLNode<E,K> *PA,   
                   AVLNode<E,K> *A, AVLNode<E,K> *B)   
{   
    //RL型的旋转   
    AVLNode<E,K> *C = B->LeftChild;   
  
    A->RightChild = C->LeftChild;   
    B->LeftChild = C->RightChild;   
    C->LeftChild = A;   
    C->RightChild = B;   
    if (PA) // A 是否有父节点   
    {   
        if (A == PA->LeftChild)   
            PA->LeftChild = C;   
        else    
            PA->RightChild = C;   
    }   
    else  
    {   
        root = C;   
    }   
  
    //设置平衡因子   
    int b = C->bf;   
    if (b == 1)   
    {   
        B->bf = -1;   
        A->bf = 0;   
    }   
    else if (b == -1)    
    {   
        B->bf = 0;   
        A->bf = 1;   
    }   
    else // b = 0   
    {   
        B->bf = A->bf = 0;   
    }   
  
    C->bf = 0;   
}   
  
template<class E, class K>   
AVLtree<E,K>& AVLtree<E,K>::Insert(const E& e)   
{   
    AVLNode<E,K> *p = root,   
                 *pp = 0,    // p的父节点   
                 *A = 0,     // 平衡因子不为0 的最后一个节点   
                 *PA;        // A的父节点   
  
    //找到可以插入的地方   
    //同时记录最后一个平衡因子不为0的节点及其父节点   
    while (p)    
    {   
        if (p->bf)    
        {   
            A = p;   
            PA = pp;   
        }   
  
        pp = p;   
  
        // 将p移向子节点   
        if (e < p->data)    
            p = p->LeftChild;   
        else if (e > p->data)    
            p = p->RightChild;   
        else    
            throw BadInput();   
  
        /*if(e <= p->data)   
            p = p->LeftChild;  
        else  
            p = p->RightChild;*/  
    }   
  
  
    AVLNode<E,K> *r = new AVLNode<E,K> (e);   
    if (root)    
    {   
        if (e < pp->data)    
            pp->LeftChild = r;   
        else    
            pp->RightChild = r;   
    }   
    else    
    {   
        root = r;   
        return *this;   
    }   
  
    //查看是否需要再平衡,还是只是简单的刷新下平衡因子   
    if(A)   
    {   
        if (A->bf < 0) // bf = -1 在插入前   
        {   
            if (e < A->data)   
            {   
                //插入到A的左子树,左子树高度加1   
                //A新的平衡因子等于0, 不需要再平衡   
                A->bf = 0;   
  
                //刷新下从A到r的平衡因子   
                FixBF(A->LeftChild,r,e);   
            }   
            else    
            {   
                //插入到A的右子树   
                //A的平衡因子为-2, 需要再平衡   
                AVLNode<E,K> *B = A->RightChild;   
  
                if (e > B->data)    
                {   
                    // RR型   
                    FixBF(B->RightChild,r,e);   
                    RRrotate(PA,A,B);   
                }   
                else    
                {      
                    // RL型   
                    FixBF(B->LeftChild,r,e);   
                    RLrotate(PA,A,B);   
                }   
            }   
        }   
        else // bf = +1 在插入前   
        {   
            if (e > A->data)   
            {   
                //插入到A的右子树,右子树高度加1   
                //A新的平衡因子等于0, 不需要再平衡   
                A->bf = 0;   
  
                //刷新下从A到r的平衡因子   
                FixBF(A->RightChild,r,e);   
            }   
            else    
            {   
                //插入到A的左子树   
                //A的平衡因子为+2, 需要再平衡   
                AVLNode<E,K> *B = A->LeftChild;   
                if (e < B->data)    
                {   
                    // LL型   
                    FixBF(B->LeftChild,r,e);   
                    LLrotate(PA,A,B);   
                }   
                else    
                {   
                    // LR型   
                    FixBF(B->RightChild,r,e);   
                    LRrotate(PA,A,B);   
                }   
            }   
        }   
    }   
    else // A一直为0, 不需要再平衡   
    {   
        //刷新下从root到r的平衡因子   
        FixBF(root,r,e);   
    }   
  
    return *this;   
}   
  
template<class E, class K>   
AVLtree<E,K>& AVLtree<E,K>::Delete(const K& k, E& e)   
{   
    // 如果元素数量超过2^60, S栈将会溢出   
    Stack<AVLNode<E,K>*> S(100);   
  
  
    AVLNode<E,K> *p = root;   
    while (p && p->data != k)   
    {   
        S.Add(p);   
        if (k < p->data)    
            p = p->LeftChild;   
        else    
            p = p->RightChild;   
    }   
  
    if (!p)    
        throw BadInput();   
  
    e = p->data;   
  
      
    //p有两个子树的情况   
    if (p->LeftChild && p->RightChild)    
    {   
        //查找p左子树里元素值最大的节点   
        S.Add(p);   
        AVLNode<E,K> *s = p->LeftChild;   
        while (s->RightChild)    
        {   
            S.Add(s);   
            s = s->RightChild;   
        }   
  
        //将p左子树里元素值最大的节点等于p   
        p->data = s->data;   
        p = s;   
    }   
  
  
    //只有一个子树的情况   
    AVLNode<E,K> *c;   
    if (p->LeftChild)    
        c = p->LeftChild;   
    else    
        c = p->RightChild;   
  
  
    if (p == root)   
    {   
       root = c;   
    }   
    else    
    {   
        if (p == S.Top()->LeftChild)   
            S.Top()->LeftChild = c;   
        else    
            S.Top()->RightChild = c;   
    }   
  
    E f = p->data; //f也许不等于e   
    delete p;   
  
    AVLNode<E,K> *q;   
    try    
    {   
       S.Delete(q);   
    }   
    catch (OutOfBounds)   
    {   
        //根节点被删除了   
        return *this;   
    }   
  
    while (q)   
    {   
        if (f <= q->data)    
        {   
            //从q的左子树删除的   
            q->bf--;   
  
            //高度并未发生改变, 不需要再做什么   
            if (q->bf == -1)    
                return *this;   
  
            if (q->bf == -2)   
            {   
                //树变得不平衡了, 需要旋转   
                AVLNode<E,K> *B = q->RightChild,   
                             *PA;  // q就是A节点   
                                   // PA是A的父节点   
                try    
                {   
                    S.Delete(PA);   
                }   
                catch (OutOfBounds)   
                {   
                    //说明A是根节点   
                    PA = 0;   
                }   
  
                switch (B->bf)    
                {   
                case 0: // L0型   
                    RRrotate(PA,q,B);   
                    B->bf = 1;   
                    q->bf = -1;   
                    return *this;   
                case 1: // L1型   
                    RLrotate(PA,q,B);   
                    break;   
                case -1:// L-1型   
                    RRrotate(PA,q,B);   
                    break;   
                }   
                   
                q = PA;   
            }   
            else // q->bf == 0   
            {   
                try    
                {   
                    S.Delete(q);   
                }   
                catch (OutOfBounds)   
                {   
                    return *this;   
                }   
            }   
        }   
      else    
      {   
            //从q的右子树删除的   
            q->bf++;   
  
            //高度并未发生改变, 不需要再做什么   
            if (q->bf == 1)    
                return *this;   
  
            if (q->bf == 2)    
            {   
                //树变得不平衡了, 需要旋转   
                AVLNode<E,K> *B = q->LeftChild,   
                             *PA;  // q就是A节点   
                                   // PA是A的父节点   
  
                try    
                {   
                    S.Delete(PA);   
                }   
                catch (OutOfBounds)   
                {   
                    //说明A是根节点   
                    PA = 0;   
                }   
                   
                switch (B->bf)    
                {   
                case 0: // R0型   
                    LLrotate(PA,q,B);   
                    B->bf = -1;   
                    q->bf = 1;   
                    return *this;   
                case 1: // R1型   
                    LLrotate(PA,q,B);   
                    break;   
                case -1: // R-1 型   
                    LRrotate(PA,q,B);   
                    break;   
                }   
  
                q = PA;   
            }   
            else // q->bf == 0   
            {   
                try  
                {   
                    S.Delete(q);   
                }   
                catch (OutOfBounds)   
                {   
                    return *this;   
                }   
            }   
        }   
    }   
  
    return *this;   
}   
  
template<class E, class K>   
void AVLtree<E,K>::InOutput(AVLNode<E,K> *t)   
{   
    if(t)    
    {   
        InOutput(t->LeftChild);   
        cout << t->data << " ";   
        InOutput(t->RightChild);   
    }   
}   
  
template<class E, class K>   
void AVLtree<E,K>::PostOutput(AVLNode<E,K> *t)   
{   
    if(t)    
    {   
        PostOutput(t->LeftChild);   
        PostOutput(t->RightChild);   
        cout << t->data << " ";   
    }   
}  
template<class E, class K>
class AVLtree 
{
public:
	AVLtree() {root = 0;}
	~AVLtree() {Erase(root);}
	bool Search(const K& k, E& e) const;
	AVLtree<E,K>& Insert(const E& e);
	AVLtree<E,K>& Delete(const K& k, E& e);
	void Ascend() {InOutput(root); cout << endl;}
	void PostOut() {PostOutput(root); cout << endl;}

private:
	AVLNode<E,K> *root;

	void Erase(AVLNode<E,K> *t);
	void InOutput(AVLNode<E,K> *t);
	void PostOutput(AVLNode<E,K> *t);
	void FixBF(AVLNode<E,K> *, AVLNode<E,K>*, const E&);
	void RRrotate(AVLNode<E,K> *, AVLNode<E,K>*, AVLNode<E,K> *);
	void LLrotate(AVLNode<E,K> *, AVLNode<E,K>*, AVLNode<E,K> *);
	void RLrotate(AVLNode<E,K> *, AVLNode<E,K>*, AVLNode<E,K> *);
	void LRrotate(AVLNode<E,K> *, AVLNode<E,K>*, AVLNode<E,K> *);
};

template<class E, class K>
void AVLtree<E,K>::Erase(AVLNode<E,K> *t)
{
	//用前序遍历的方式删除所有节点
	if (t) 
	{
		Erase(t->LeftChild);
		Erase(t->RightChild);
		delete t;
	}
}

template<class E, class K>
bool AVLtree<E,K>::Search(const K& k, E &e) const
{
	AVLNode<E,K> *p = root;
	while (p)
	{
		if (k < p->data) 
			p = p->LeftChild;
		else if (k > p->data) 
			p = p->RightChild;
		else 
		{
			e = p->data;
			return true;
		}
	}
	return false;
}

template<class E, class K>
void AVLtree<E,K>::FixBF(AVLNode<E,K> *q,
                         AVLNode<E,K> *r, const E &e)
{
	//从q到r的平衡因子通常为0
	//根据实际情况改变成 +1 或 -1
	while (q != r)
	{
		if (e < q->data) 
		{
			q->bf = 1;
			q = q->LeftChild;
		}
		else 
		{
			q->bf = -1;
			q = q->RightChild;
		}
	}
}

template<class E, class K>
void AVLtree<E,K>::LLrotate(AVLNode<E,K> *PA, AVLNode<E,K> *A, AVLNode<E,K> *B)
{
	//LL型的旋转
	A->LeftChild = B->RightChild;
	B->RightChild = A;
	if (PA) // A 是否有父节点
	{
		if (A == PA->LeftChild)
			PA->LeftChild = B;
		else 
			PA->RightChild = B;
	}
	else
	{
		root = B;
	}

	//设置平衡因子
	A->bf = B->bf = 0;
}

template<class E, class K>
void AVLtree<E,K>::RRrotate(AVLNode<E,K> *PA, AVLNode<E,K> *A, AVLNode<E,K> *B)
{
	//RR型的旋转
	A->RightChild = B->LeftChild;
	B->LeftChild = A;
	if (PA) // A 是否有父节点
	{
		if (A == PA->LeftChild)
			PA->LeftChild = B;
		else 
			PA->RightChild = B;
	}
	else
	{
		root = B;
	}

	//设置平衡因子
	A->bf = B->bf = 0;
}

template<class E, class K>
void AVLtree<E,K>::LRrotate(AVLNode<E,K> *PA,
                   AVLNode<E,K> *A, AVLNode<E,K> *B)
{
	//LR型的旋转
	AVLNode<E,K> *C = B->RightChild;


	A->LeftChild = C->RightChild;
	B->RightChild = C->LeftChild;
	C->LeftChild = B;
	C->RightChild = A;
	if (PA) // A 是否有父节点
	{
		if (A == PA->LeftChild)
			PA->LeftChild = C;
		else
			PA->RightChild = C;
	}
	else 
	{
		root = C;
	}

	//设置平衡因子
	int b = C->bf;
	if (b == 1) 
	{
		B->bf = 0;
		A->bf = -1;
	}
	else if (b == -1) 
	{
		B->bf = 1;
		A->bf = 0;
	}
	else // b = 0
	{
		B->bf = A->bf = 0;
	}

	C->bf = 0;
}

template<class E, class K>
void AVLtree<E,K>::RLrotate(AVLNode<E,K> *PA,
                   AVLNode<E,K> *A, AVLNode<E,K> *B)
{
	//RL型的旋转
	AVLNode<E,K> *C = B->LeftChild;

	A->RightChild = C->LeftChild;
	B->LeftChild = C->RightChild;
	C->LeftChild = A;
	C->RightChild = B;
	if (PA) // A 是否有父节点
	{
		if (A == PA->LeftChild)
			PA->LeftChild = C;
		else 
			PA->RightChild = C;
	}
	else
	{
		root = C;
	}

	//设置平衡因子
	int b = C->bf;
	if (b == 1)
	{
		B->bf = -1;
		A->bf = 0;
	}
	else if (b == -1) 
	{
		B->bf = 0;
		A->bf = 1;
	}
	else // b = 0
	{
		B->bf = A->bf = 0;
	}

	C->bf = 0;
}

template<class E, class K>
AVLtree<E,K>& AVLtree<E,K>::Insert(const E& e)
{
	AVLNode<E,K> *p = root,
				 *pp = 0,    // p的父节点
				 *A = 0,     // 平衡因子不为0 的最后一个节点
				 *PA;        // A的父节点

	//找到可以插入的地方
	//同时记录最后一个平衡因子不为0的节点及其父节点
	while (p) 
	{
		if (p->bf) 
		{
			A = p;
			PA = pp;
		}

		pp = p;

		// 将p移向子节点
		if (e < p->data) 
			p = p->LeftChild;
		else if (e > p->data) 
			p = p->RightChild;
		else 
			throw BadInput();

		/*if(e <= p->data) 
			p = p->LeftChild;
		else
			p = p->RightChild;*/
	}


	AVLNode<E,K> *r = new AVLNode<E,K> (e);
	if (root) 
	{
		if (e < pp->data) 
			pp->LeftChild = r;
		else 
			pp->RightChild = r;
	}
	else 
	{
		root = r;
		return *this;
	}

	//查看是否需要再平衡,还是只是简单的刷新下平衡因子
	if(A)
	{
		if (A->bf < 0) // bf = -1 在插入前
		{
			if (e < A->data)
			{
				//插入到A的左子树,左子树高度加1
				//A新的平衡因子等于0, 不需要再平衡
				A->bf = 0;

				//刷新下从A到r的平衡因子
				FixBF(A->LeftChild,r,e);
			}
			else 
			{
				//插入到A的右子树
				//A的平衡因子为-2, 需要再平衡
				AVLNode<E,K> *B = A->RightChild;

				if (e > B->data) 
				{
					// RR型
					FixBF(B->RightChild,r,e);
					RRrotate(PA,A,B);
				}
				else 
				{	
					// RL型
					FixBF(B->LeftChild,r,e);
					RLrotate(PA,A,B);
				}
			}
		}
		else // bf = +1 在插入前
		{
			if (e > A->data)
			{
				//插入到A的右子树,右子树高度加1
				//A新的平衡因子等于0, 不需要再平衡
				A->bf = 0;

				//刷新下从A到r的平衡因子
				FixBF(A->RightChild,r,e);
			}
			else 
			{
				//插入到A的左子树
				//A的平衡因子为+2, 需要再平衡
				AVLNode<E,K> *B = A->LeftChild;
				if (e < B->data) 
				{
					// LL型
					FixBF(B->LeftChild,r,e);
					LLrotate(PA,A,B);
				}
				else 
				{
					// LR型
					FixBF(B->RightChild,r,e);
					LRrotate(PA,A,B);
				}
			}
		}
	}
	else // A一直为0, 不需要再平衡
	{
		//刷新下从root到r的平衡因子
		FixBF(root,r,e);
	}

	return *this;
}

template<class E, class K>
AVLtree<E,K>& AVLtree<E,K>::Delete(const K& k, E& e)
{
	// 如果元素数量超过2^60, S栈将会溢出
	Stack<AVLNode<E,K>*> S(100);


	AVLNode<E,K> *p = root;
	while (p && p->data != k)
	{
		S.Add(p);
		if (k < p->data) 
			p = p->LeftChild;
		else 
			p = p->RightChild;
	}

	if (!p) 
		throw BadInput();

	e = p->data;

   
	//p有两个子树的情况
	if (p->LeftChild && p->RightChild) 
	{
		//查找p左子树里元素值最大的节点
		S.Add(p);
		AVLNode<E,K> *s = p->LeftChild;
		while (s->RightChild) 
		{
			S.Add(s);
			s = s->RightChild;
		}

		//将p左子树里元素值最大的节点等于p
		p->data = s->data;
		p = s;
	}


	//只有一个子树的情况
	AVLNode<E,K> *c;
	if (p->LeftChild) 
		c = p->LeftChild;
	else 
		c = p->RightChild;


	if (p == root)
	{
	   root = c;
	}
	else 
	{
		if (p == S.Top()->LeftChild)
			S.Top()->LeftChild = c;
		else 
			S.Top()->RightChild = c;
	}

	E f = p->data; //f也许不等于e
	delete p;

	AVLNode<E,K> *q;
	try 
	{
	   S.Delete(q);
	}
	catch (OutOfBounds)
	{
		//根节点被删除了
		return *this;
	}

	while (q)
	{
		if (f <= q->data) 
		{
			//从q的左子树删除的
			q->bf--;

			//高度并未发生改变, 不需要再做什么
			if (q->bf == -1) 
				return *this;

			if (q->bf == -2)
			{
				//树变得不平衡了, 需要旋转
				AVLNode<E,K> *B = q->RightChild,
							 *PA;  // q就是A节点
							       // PA是A的父节点
				try 
				{
					S.Delete(PA);
				}
				catch (OutOfBounds)
				{
					//说明A是根节点
					PA = 0;
				}

				switch (B->bf) 
				{
				case 0: // L0型
					RRrotate(PA,q,B);
					B->bf = 1;
					q->bf = -1;
					return *this;
				case 1: // L1型
					RLrotate(PA,q,B);
					break;
				case -1:// L-1型
					RRrotate(PA,q,B);
					break;
				}
				
				q = PA;
			}
			else // q->bf == 0
			{
				try 
				{
					S.Delete(q);
				}
				catch (OutOfBounds)
				{
					return *this;
				}
			}
		}
	  else 
	  {
			//从q的右子树删除的
			q->bf++;

			//高度并未发生改变, 不需要再做什么
			if (q->bf == 1) 
				return *this;

			if (q->bf == 2) 
			{
				//树变得不平衡了, 需要旋转
				AVLNode<E,K> *B = q->LeftChild,
							 *PA;  // q就是A节点
								   // PA是A的父节点

				try 
				{
					S.Delete(PA);
				}
				catch (OutOfBounds)
				{
					//说明A是根节点
					PA = 0;
				}
		        
				switch (B->bf) 
				{
				case 0: // R0型
					LLrotate(PA,q,B);
					B->bf = -1;
					q->bf = 1;
					return *this;
				case 1: // R1型
					LLrotate(PA,q,B);
					break;
				case -1: // R-1 型
					LRrotate(PA,q,B);
					break;
				}

				q = PA;
			}
			else // q->bf == 0
			{
				try
				{
					S.Delete(q);
				}
				catch (OutOfBounds)
				{
					return *this;
				}
			}
		}
	}

	return *this;
}

template<class E, class K>
void AVLtree<E,K>::InOutput(AVLNode<E,K> *t)
{
	if(t) 
	{
		InOutput(t->LeftChild);
		cout << t->data << " ";
		InOutput(t->RightChild);
	}
}

template<class E, class K>
void AVLtree<E,K>::PostOutput(AVLNode<E,K> *t)
{
	if(t) 
	{
		PostOutput(t->LeftChild);
		PostOutput(t->RightChild);
		cout << t->data << " ";
	}
} 

view plaincopy to clipboardprint?
#ifndef AVLNode_   
#define AVLNode_   
  
template <class E, class K> class AVLtree;   
template <class E, class K> class AVLtree2;   
template <class E, class K> class DAVLtree;   
  
template <class E, class K>   
class AVLNode    
{   
    friend AVLtree<E,K>;   
    friend AVLtree2<E,K>;   
    friend DAVLtree<E,K>;   
public:   
  
    AVLNode() {LeftChild = RightChild = 0;}   
    AVLNode(const E& e){data = e; bf = 0; LeftChild = RightChild = 0; height = 0; }   
  
private:   
  
    E data;   
    int bf;   
    int height;   
    AVLNode<E,K> *LeftChild,   
                *RightChild;   
};   
  
#endif  


stack的手动实现

template<class T>   
class Stack    
{   
public:   
    Stack(int MaxStackSize = 10);   
    ~Stack() {delete [] stack;}   
    bool IsEmpty() const {return top == -1;}   
    bool IsFull() const {return top == MaxTop;}   
    T Top() const;   
    Stack<T>& Add(const T& x);   
    Stack<T>& Delete(T& x);   
private:   
    int top;   
    int MaxTop;   
    T *stack;   
};   
  
template<class T>   
Stack<T>::Stack(int MaxStackSize)   
{   
    MaxTop = MaxStackSize - 1;   
    stack = new T[MaxStackSize];   
    top = -1;   
}   
  
template<class T>   
T Stack<T>::Top() const  
{   
    if (IsEmpty())    
        throw OutOfBounds();   
  
    return stack[top];   
}   
  
template<class T>   
Stack<T>& Stack<T>::Add(const T& x)   
{   
    if (IsFull())    
        throw NoMem();   
  
    stack[++top] = x;   
    return *this;   
}   
  
template<class T>   
Stack<T>& Stack<T>::Delete(T& x)   
{   
   if (IsEmpty())    
       throw OutOfBounds();   
  
   x = stack[top--];   
   return *this;   
}  


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值