平衡树AVLTree的代码

也是以前写的程序,是实现平衡树的,现在都有点看不懂了,拿出来晒晒.
AVL算法参考: http://www.nocow.cn/index.php/AVL%E6%A0%91
-----------------------------------------------------------------------------------------

describe.h是用来描述返回值的(当初居然用const int,而没有用enum,汗~!)

#ifndef DESCRIBE_H
#define DESCRIBE_H

const int NODE_INSERT_SUCCESS = 0;
const int NODE_NULL_ERROR = 1;
const int NODE_EXIST_ERROR =2;
const int NODE_NOTEXIST_ERROR = 3;
const int NODE_DELETE_SUCCESS = 4;

#endif  // DESCRIBE_H

下面就是avltree.h的实现了,由于是用template实现,并且gcc好像不支持template实现放在.cpp文件,因此就写
在一个头文件里面了. (当时是在Linux用gcc调试的,那叫一个累啊,现在都快忘了,皑皑).

#ifndef AVLTREE_H
#define AVLTREE_H

//-INCLUDES---------------------------------------------------------------------------------
#include "describe.h"
#include<iostream>
using namespace std;

//
// The definiation of tree node.
//
template<class T>
class TreeNode
{
public:

    // Default Constructor
    TreeNode()
    {
        m_pLeft = NULL;
        m_pRight = NULL;
    }
    
    // Constructor, parameter data is assigned to m_data
    TreeNode(const T& data)
    {
        m_data = data;
        m_pLeft = NULL;
        m_pRight = NULL;
    }
    
    // Copy Constructor
    TreeNode(const TreeNode& node)
    {
        m_data = node.data;
        m_pLeft = NULL;
        m_pRight = NULL;
    }
    
    // Destructor
    ~TreeNode()
    {
    }
   
    // Get the data of current node.
    T GetData()
    {
        return m_data;
    }

    // Print the data of current node.
    void Print()
    {
        cout << m_data << " ";      
    }

public:
    T m_data;
    // Left child node of current node.
    TreeNode<T>* m_pLeft;
    // Right child node of current node.
    TreeNode<T>* m_pRight;
};

//
// The definiation of AVL tree.
//

template<class T>
class AVLTree
{
public:
    // Default Constructor
    AVLTree();

    // Copy Constructor
    AVLTree(const AVLTree<T>& tree);

    // Operator Assigment
    AVLTree& operator=(const AVLTree<T>& tree);

    // Destructor
    ~AVLTree();

    // Erase all data in AVLTree
    void Erase();

    // Get Root node of tree
    TreeNode<T> *GetRoot();

    // Get Heigh:t of AVLTree
    int GetHeight(TreeNode<T> *pNode);

    // Insert Node into AVLTree
    int InsertNode(const T& data);

    // Delete Node from AVLTree
    int DeleteNode(const T& data);

    // Search Node from AVLTree
    bool Search(const T& data);

    // Estamite AVLTree is balance
    bool IsBalance(TreeNode<T> *pNode);

    // Get height between left tree and right tree
    int GetLRHeight(TreeNode<T> *pNode);

    // Previous order to visit AVLTree
    void PreOrder(TreeNode<T> *pNode);

    // Post order to visit AVLTree
    void PostOrder(TreeNode<T> *pNode);

    // Post sort of AVL Tree
    void PostSort(TreeNode<T> *pNode);

    // Inorder to visit AVLTree
    void InOrder(TreeNode<T> *pNode);

    // Visit AVLNode
    void Visit(TreeNode<T> *pNode);

    // Print AVLTree
    void Print();

    // Left Rotate
    TreeNode<T>* LeftRotate(TreeNode<T> *pNode, TreeNode<T> *pParent);

    // Right Rotate
    TreeNode<T>* RightRotate(TreeNode<T> *pNode, TreeNode<T> *pParent);

    // Get Parent Node
    TreeNode<T>* GetParent(TreeNode<T> *pNode);

private:
    // The balance gene of AVL Tree.
    int m_nBalance;

    // The root node of AVL Tree.
    TreeNode<T> *m_pRoot;
};

/**
 * Description: Constructor
 * Parameter: None;
 * Return: None
 */
template<class T>
AVLTree<T>::AVLTree()
{
    m_pRoot = NULL;
    m_nBalance == 0;
}

/**
 * Description: Copy Constructor
 * Parameter: const AVLTree& tree
 * Return: None.
 */
template<class T>
AVLTree<T>::AVLTree(const AVLTree<T>& tree)
{
   InOrder(tree.m_pRoot);
}

/**
 * Description: Assigment Operator
 * Parameter: const AVLTree& tree
 * Return: None.
 */
template<class T>
AVLTree<T>& AVLTree<T>::operator=(const AVLTree<T>& tree)
{
    Erase();
    InOrder(tree.m_pRoot);
    return *this;
}

/**
 * Description: Destructor
 * Parameter: NULL
 * return: NULL
 */
template<class T>
AVLTree<T>::~AVLTree()
{
    Erase();
}

/**
 *
 *
 *
 */
template<class T>
void AVLTree<T>::Erase()
{
    PostOrder(m_pRoot);
}
/**
 * Description: Get Height of AVLTree
 * Parameter: NULL
 * Return: Height of AVLTree
 */
template<class T>
int AVLTree<T>::GetHeight(TreeNode<T>* pNode)
{
    // If visit at bottom of tree
    if (NULL == pNode)
    {
        return 0;
    }
    int nLeftHeight = GetHeight(pNode -> m_pLeft);
    int nRightHeight = GetHeight(pNode -> m_pRight);
    if (nLeftHeight > nRightHeight)
    {
        return ++nLeftHeight;
    }
    else
    {
        return ++nRightHeight;
    }
}

/**
 * Description: Get root node of AVLTree
 * Parameter: NULL
 * Return: NULL
 */
template<class T>
TreeNode<T>* AVLTree<T>::GetRoot()
{
    return m_pRoot;
}

/**
 * Description: Insert tree node into AVLTree, and keep searching
 * and balance
 * Parameter: A tree node pointer
 * Return: Operation result
 */
template<class T>
int AVLTree<T>::InsertNode(const T& data)
{
    TreeNode<T>* pNode = NULL;
    pNode = new TreeNode<T>(data);

    // If m_pRoot is null, assign pNode to m_pRoot
    if (NULL == m_pRoot)
    {
        m_pRoot = new TreeNode<T>;

        // It will call assignment operation here.
        m_pRoot = pNode;

        return NODE_INSERT_SUCCESS;    
    }    
    
    TreeNode<T>* pTempNode = m_pRoot;
    while (NULL != pTempNode)
    {
        // pNode is smaller than tree node
        if (pTempNode -> m_data > data)
        {
            // If left child has element, continue view; else add
            // element at left child
            if (NULL != pTempNode -> m_pLeft)
            {
                pTempNode = pTempNode -> m_pLeft;
            }
            else
            {
                pTempNode -> m_pLeft = pNode;
                break;
            }
        }            
        // pNode is bigger than tree node
        else if (pTempNode -> m_data < data)
        {
            // If right child has element, continue view; else add
            // element at right child
            if (NULL != pTempNode -> m_pRight)
                {
                pTempNode = pTempNode -> m_pRight;
            }
            else
            {
                pTempNode -> m_pRight = pNode;
                break;
            }
        }
    
        // pNode equal tree node, can't be inserted into tree
        else if (pTempNode -> m_data == data)
        {
            delete pNode;
            pNode = NULL;
            return NODE_EXIST_ERROR;
        }
    }

    // If tree is not balance
    return NODE_INSERT_SUCCESS;
}

/**
 * Description: Delete tree node from AVLTree, and keep searching
 * and balance
 * Parameter: A tree node pointer
 * Return: Operation result
 */
template<class T>
int AVLTree<T>::DeleteNode(const T& data)
{
    // AVLTree is empty
    cout << "Delete Data is: " << data << endl;
    if (NULL == m_pRoot)
    {
        return NODE_NOTEXIST_ERROR;
    }    

    TreeNode<T>* pCur = m_pRoot;
    TreeNode<T>* pParent = NULL;
    
    // Search If delete node existed
    while ((NULL != pCur) && (pCur -> m_data != data))
    {
        pParent = pCur;  // Store pCur's father node

        if (pCur -> m_data < data)
        {
            pCur = pCur -> m_pRight;
        }
        else if ( pCur -> m_data > data)
        {
            pCur = pCur -> m_pLeft;
        }
    }

    //No found delete data
    if (NULL == pCur)
    {
        cout << "No found delete data" << endl;
        return NODE_NOTEXIST_ERROR;
    }

    //If pCur has left child.
    if ((NULL != pCur -> m_pLeft) && (NULL != pCur -> m_pRight))
    {
        //Move Left tree's biggest child to pCur and delete pCu.
        TreeNode<T>* pReplace = pCur -> m_pLeft;
        TreeNode<T>* pTempParent = pCur;

        // Find biggest element on delete Node's left tree
        while (NULL != pReplace -> m_pRight)
        {
            pTempParent = pReplace;
            pReplace = pReplace -> m_pRight;
        }

        //Move biggest element to delete node
        pCur -> m_data = pReplace -> m_data;
        cout << "pReplace Value:" << pReplace -> m_data << endl;
        pCur = pReplace;
        
        // For testing
        pParent = pTempParent;
    }

    cout << "pCur Value:" << pCur -> m_data << endl;
    TreeNode<T>* temp;

    if (NULL != pCur ->m_pLeft)
    {
        temp = pCur->m_pLeft;
    
    }
    else
    {
        temp = pCur->m_pRight;
    }

    // Delete node is root
    if (pCur == m_pRoot)
    {
        m_pRoot = temp;
    }
    else
    {
        if (pCur == pParent -> m_pLeft)
        {
            pParent -> m_pLeft = temp;
        }
        else
        {
            pParent -> m_pRight = temp;
        }
    }

    delete pCur;
    return NODE_DELETE_SUCCESS;
}

/**
 * Description: Search tree node from AVLTree
 * Parameter: A node pointer
 * Return: If data is in tree, return true; else return false
 */
template<class T>
bool AVLTree<T>::Search(const T& data)
{
    TreeNode<T> *node = m_pRoot;

    while (NULL != node)
    {
        // Found data !
        if (node->m_data == data)
        {
            return true;
        }
        
        else if (node->m_data > data)
        {
            node = node->m_pLeft;
        }
        else
        {
            node = node->m_pRight;
        }
    }

    return false;
}

/**
 * Description: Check tree is balance or not
 * Parameter: A node pointer
 * Return: If tree is balance, return true, else return false
 */
template<class T>
bool AVLTree<T>::IsBalance(TreeNode<T>* pNode)
{
    if (pNode == NULL)
    {
        cout << "node is null" << endl;
        return false;
    }
    else
    {
        int m_nDis = GetLRHeight(pNode);

        if ((m_nDis >= -1) && (m_nDis <= 1))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

/**
 * Description: Previous order to visit AVLTree
 * Parameter: NULL
 * Return: NULL
 */
template<class T>
void AVLTree<T>::PreOrder(TreeNode<T>* pNode)
{
    if (NULL == pNode)
    {
        return;       
    }

    Visit(pNode);
    PreOrder(pNode -> m_pLeft);
    PreOrder(pNode -> m_pRight);
}

/**
 * Description: Post order to visit AVLTree, left child -> right child -> root.
 * Parameter: NULL
 * Return: NULL
 */
template<class T>
void AVLTree<T>::PostOrder(TreeNode<T> *pNode)
{
    if (NULL == pNode)
    {
        return;        
    }

    PostOrder(pNode->m_pLeft);
    PostOrder(pNode->m_pRight);

    // Delete the current node.
    delete pNode;
    pNode = NULL;

}

/**
 * Description: In order to visit AVLTree
 * Parameter: NULL
 * Return: NULL
 */
template<class T>
void AVLTree<T>::InOrder(TreeNode<T>* pNode)
{
    if (NULL == pNode)
    {
        return;
    }

    InOrder(pNode -> m_pLeft);
    InsertNode(pNode -> m_data);
    InOrder(pNode -> m_pRight);
}

/**
 * Description: call pNode's print function
 * Parameter: NULL
 * Return: NULL
 */
template<class T>
void AVLTree<T>::Visit(TreeNode<T>* pNode)
{
    if (NULL != pNode)
    {
        pNode -> Print();
    }    
}

/**
 * Description: Print AVLTree by previous order
 * Parameter: NULL
 * Return: NULL
 */
template<class T>
void AVLTree<T>::Print()
{
    PreOrder(m_pRoot);
}

/**
 * Description: Left rotate of child tree
 * Parameter: NULL
 * Return: NULL
 */
template<class T>
TreeNode<T>* AVLTree<T>::LeftRotate(TreeNode<T>* pNode, TreeNode<T>* pParent)
{
    // Rotate tree node is empty
    if (NULL == pNode)
    {
        return NULL;
    }
    // deal with root node
    if (pNode == m_pRoot)
    {
        m_pRoot = pNode -> m_pLeft;
        pNode -> m_pLeft = m_pRoot -> m_pRight;
        m_pRoot -> m_pRight = pNode;
        return m_pRoot;
    }  
    else
    {
        T data = pNode -> m_data;    
        TreeNode<T>* pTemp = pNode;
        pNode = pNode -> m_pLeft;
        pTemp -> m_pLeft = pNode -> m_pRight;
        pNode -> m_pRight = pTemp;
        if ((pParent -> m_pLeft != NULL) &&
            (data == pParent -> m_pLeft -> m_data))
        {
            pParent -> m_pLeft = pNode;
        }
        else if ((pParent -> m_pRight != NULL) &&
         (data == pParent -> m_pRight -> m_data))
        {
            pParent -> m_pRight = pNode;
        }
        return pNode;
    }
}

/**
 * Description: Right rotate of child tree
 * Parameter: NULL
 * Return: NULL
 */
template<class T>
TreeNode<T>* AVLTree<T>::RightRotate(TreeNode<T>* pNode, TreeNode<T>* pParent)
{
    if (NULL == pNode)
    {
        return NULL;
    }
    // deal with root node
    if (pNode == m_pRoot)
    {
        m_pRoot = pNode -> m_pRight;
        pNode -> m_pRight = m_pRoot -> m_pLeft;
        m_pRoot -> m_pLeft = pNode;
        return m_pRoot;
    }
    else
    {
        T data = pNode -> m_data;
        TreeNode<T>* pTemp = pNode;
        pNode = pNode -> m_pRight;
        pTemp -> m_pRight = pNode -> m_pLeft;
        pNode -> m_pLeft = pTemp;
    
        if ((NULL != pParent -> m_pLeft) &&
            (data == pParent -> m_pLeft -> m_data))
        {
            pParent -> m_pLeft = pNode;
        }
        else if ((NULL != pParent -> m_pRight)
              && (data == pParent -> m_pRight -> m_data))
        {
            pParent -> m_pRight = pNode;
        }
        return pNode;
    }
}

template<class T>
int AVLTree<T>::GetLRHeight(TreeNode<T>* pNode)
{
    if(NULL == pNode)
    {
        return 0;
    }
    int nLeft = GetHeight(pNode -> m_pLeft);
    int nRight = GetHeight(pNode -> m_pRight);
    return nLeft - nRight;
}

template<class T>
TreeNode<T>* AVLTree<T>::GetParent(TreeNode<T>* pNode)
{
    if ((pNode == NULL) || (m_pRoot == NULL) || (pNode == m_pRoot))
    {
        return NULL;
    }
    
    TreeNode<T>* pTemp = m_pRoot;
    T eData = pNode -> m_data;
    if (eData != m_pRoot -> m_data)
    {
        while (!((pTemp -> m_pLeft == NULL) &&
           (pTemp -> m_pRight == NULL)))
        {
            if (pTemp -> m_pLeft != NULL && pTemp -> m_pRight != NULL)
            {
                if ((pTemp -> m_pLeft -> m_data == eData) ||
                (pTemp -> m_pRight -> m_data == eData))
                {
                    return pTemp;
                }
                else if (pTemp -> m_data > eData)
                {
                    pTemp = pTemp -> m_pLeft;
                }
                else if (pTemp -> m_data < eData)
                {
                    pTemp = pTemp -> m_pRight;
                }
            }
            else if (pTemp -> m_pLeft != NULL &&
                    pTemp -> m_pRight == NULL)
        
            {
                if (pTemp -> m_pLeft -> m_data == eData)
                {
                    return pTemp;
                }
                else if (pTemp -> m_data > eData)
                {
                    pTemp = pTemp -> m_pLeft;
                }
            }
            else if (pTemp -> m_pRight != NULL &&
                     pTemp -> m_pLeft == NULL)
            {
            
                if (pTemp -> m_pRight -> m_data == eData)
                {
                    return pTemp;
                }
                else if (pTemp -> m_data < eData)
                {
                    pTemp = pTemp -> m_pRight;
                }
            }
        }
        return NULL;    
    }
    else
    {
        return NULL;
    }
}


template<class T>
void AVLTree<T>::PostSort(TreeNode<T>* pNode)
{
    if (NULL == pNode)
    {
        return;
    }
   // Print();
    cout << endl;
    PostSort(pNode -> m_pLeft);
    PostSort(pNode -> m_pRight);
    if (IsBalance(pNode) == true)
    {
        return;
    }
    else
    {
        TreeNode<T>* pParent = GetParent(pNode);
    while (false == IsBalance(pNode))
    {    
        TreeNode<T>* pRecord = NULL;    
            if (GetLRHeight(pNode) < -1)
            {
        if (GetLRHeight(pNode -> m_pRight) == 1)
        {
            TreeNode<T>* Ptr = LeftRotate(pNode -> m_pRight, pNode);
            pNode -> m_pRight = Ptr;
        }
            pRecord = RightRotate(pNode, pParent);
            pNode = pRecord;
        }
        else if (GetLRHeight(pNode) > 1)
            {
        // RL style
        if (GetLRHeight(pNode -> m_pLeft) == -1)
        {
            TreeNode<T>* Ptr = RightRotate(pNode -> m_pLeft, pNode);
            pNode -> m_pLeft = Ptr;
            }
            pRecord = LeftRotate(pNode, pParent);
        pNode = pRecord;
        }
    }
    }
    //Print();
}

#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值