AVL树非递归实现插入和删除例程

原理:用一个栈把插入和删除时搜索路径记录下来,按照一般二叉树执行了插入,删除操作后再原路返回,修改高度信息和进行旋转操作使满足AVL平衡条件。

 

//AVL树模板(部分)
#ifndef AVLTree_h
#define AVLTree_h
#include <iostream>
#include <stack>  //记录删除时遍历路径
template<typename Comparable>
class AVLTree
{
private:
    struct AvlNode //树结点的定义
    {
    	Comparable element;
        AvlNode *left;
        AvlNode *right;
        int height;
        AvlNode(const Comparable &theElement,AvlNode *lt=NULL,AvlNode *rt=NULL,int h=0)
            :element(theElement),left(lt),right(rt),height(h){}
    };
         AvlNode *root; //根节点的声明
    inline int max(int a,int b)  //计算两整数最大值,在算树高度时总是用到
    {
        if(a>b)return a;
        else return b;
    }
    inline int height(AvlNode *t)const  //计算高度
          {
        return NULL==t ? -1 :t->height;
    }
    void adjust(AvlNode *&t)  //调整使符合AVL条件
    {
                  if(height(t->left)-height(t->right)==2)
                if(height(t->left->right)<height(t->left->left))
                    rotateWithLeftChild(t);
                else 
                    doubleWithLeftChild(t);
        else if(height(t->right)-height(t->left)==2)
                if(height(t->right->left)<height(t->right->right))
                    rotateWithRightChild(t);
                else 
                    doubleWithRightChild(t);

    }
    bool insert(const Comparable &x,AvlNode *&t) //插入元素,非递归
    {
        stack<AvlNode**> searchp;
        AvlNode **iter=&t;
        while((*iter)!=NULL)
        {
            searchp.push(iter);
            if(x<(*iter)->element) iter=&(*iter)->left;
            else if((*iter)->element<x) iter=&(*iter)->right;
            else return false;  //重复
        }
        *iter=new AvlNode(x);
        while(!searchp.empty())  //开始回溯
        {
            AvlNode** backp=searchp.top();
            searchp.pop();
            (*backp)->height=max(height((*backp)->left),height((*backp)->right))+1;
            adjust(*backp);
        }
        return true;
    }
    bool remove(const Comparable &x,AvlNode *&t)  //移除元素,非递归
    {
        stack<AvlNode**> searchp;
        AvlNode **iter=&t;
        while(*iter!=NULL)
        {
            searchp.push(iter);
            if(x<(*iter)->element) iter=&((*iter)->left);
                else if((*iter)->element<x) iter=&((*iter)->right);
                else
                {
                    if((*iter)->left!=NULL&&(*iter)->right!=NULL) //Two child
                    {
                        AvlNode **oldit=iter;
                        iter=&((*iter)->right);
                        searchp.push(iter);
                        while((*iter)->left!=NULL)
                        {
                            iter=&((*iter)->left);  //查找要删除的结点按中序遍历后一个结点
                            searchp.push(iter);
                        }
                        (*oldit)->element=(*iter)->element;
                    }
                    *iter=((*iter)->left!=NULL)?(*iter)->left:(*iter)->right;
                    delete *(searchp.top());
                    searchp.pop();
                    while(!searchp.empty())  //开始回溯
                    {
                        AvlNode** backp=searchp.top();
                        searchp.pop();
                        (*backp)->height=max(height((*backp)->left),height((*backp)->right))+1;
                        adjust(*backp);
                    }
                    return true;
                }
        }
        return false;
    }
    void rotateWithRightChild(AvlNode *& k1) //单旋转
    {
        AvlNode *k2=k1->right;
        k1->right=k2->left;
        k2->left=k1;
        k1->height=max(height(k1->left),height(k1->right))+1;
        k2->height=max(height(k2->right),k1->height)+1;
        k1=k2;
    }
    void rotateWithLeftChild(AvlNode *& k2)  //单旋转II
    {
        AvlNode *k1=k2->left;
        k2->left=k1->right;
        k1->right=k2;
        k2->height=max(height(k2->left),height(k2->right))+1;
        k1->height=max(height(k2->left),k2->height)+1;
        k2=k1;
    }
    void doubleWithLeftChild(AvlNode *& k3)  //双旋转
    {
        rotateWithRightChild(k3->left);
        rotateWithLeftChild(k3);
    }
    void doubleWithRightChild(AvlNode *& k4)  //双旋转II
    {
        rotateWithLeftChild(k4->left);
        rotateWithRightChild(k4);
    }
//…………
}

    原文作者:AVL树
    原文地址: https://blog.csdn.net/abacn/article/details/7610508
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞