二叉树-相关的算法和实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Windgs_YF/article/details/86520530

//////////////////////////////////////////////////////////////////////
//文件名称:BinaryTreeNode.h
//功能描述:
//版本说明:BinaryTreeNode API
//            
//编写作者:2012.02.21 yanfeng.hu QQ:[email protected] WX:windgs
//
//修改情况:完成基本功能搭建 V1.0.0
//
//////////////////////////////////////////////////////////////////////
/*
最近在温习mysql的设计架构原理和详解的时候,又重新温习了一遍索引的设计,涉及到了B-树、B+-树、T-树等一些算法,这些都是大学的时候学习过,07年参加工作后就没有怎么太涉及,因为从事C++研发游戏项目
使用的都是C++标准库STL中的各种容器和各种算法,真正自己写的并不多,所以还是想自己掌握下里面的算法,提升一下自己的技术,做技术的千万不能懒,学到手里都是活~~~~~
一、二叉树概念
    在大学的时候计算机书籍中已经接触,二叉树是每个结点有左右两个孩子的树形结构。因为都是面向对象的思想,所以可以在生活实践中结合很多场景设计进去。通常可以把孩子结点,叫做”左结点“和”右结点“
    由左结点和右结点他们自己也构成了有个二叉树。二叉树是递归定义的,所以左右的孩子次序是固定的,不能颠倒,但是有些也采用非递归算法。
二、二叉排序树
    二叉排序树又叫二叉查找树或者二叉搜索树,必须满足下面的条件:
    1)若左子树不空,则左子树上所有结点的值均小于它的父结点的值;
    2)若右子树不空,则右子树上所有结点的值均大于它的父结点的值
    3)左、右子树也分别为二叉排序树
    4)不存在键值相等的节点。(具体原因不详,可能是想mqp一样,不允许存在相同的key)
三、二叉树结点包含四个固定的成员
    1)结点的数据域
    2)指向父结点的指针域
    3)指向左子结点的指针域
    4)指向右子结点的指针域
    结点的数据域、指向父结点的指针域从TreeNode模板类继承而来。

    下面主要看算法和具体实现代码。
*/

//根据指针调用Release接口
#ifndef SAFE_RELEASE
    #define SAFE_RELEASE(x) if((x)!=NULL) { (x)->Release(); (x)=NULL; }
#endif//SAFE_RELEASE
#

template<typename T>
class TreeNode
{
protected:
    int m_nValue;                                    //具体结点的数值
    TreeNode<T>*         m_pParentNode;            //父结点指针
}
///二叉树

template<typename T>
class BinaryTreeNode : public TreeNode<T>
{
public:
    //构造函数
    BinaryTreeNode()
    {
        m_pLeftNode = NULL;
        m_pRightNode = NULL;
    }
    //析构函数
    virtual ~BinaryTreeNode()
    {

    }

protected:
    BinaryTreeNode<T>* m_pLeftNode;                //左结点指针
    BinaryTreeNode<T>* m_pRightNode;            //右结点指针

public:
    //工厂方法-创建二叉树-排序树-static fuction
    static BinaryTreeNode<T>* CreateNew()
    {
        BinaryTreeNode<T>* pNewTreeNode = new BinaryTreeNode<T>();
        if (!pNewTreeNode)
        {
            return NULL;
        }

        return pNewTreeNode;
    }

    //释放资源
    virtual bool Release()
    {
        delete this; 
        return TRUE;         
    }

    //////////////////////////////////////////////////////////////////////
    /*
     *  根据具体值从根节点查找元素
     *  参数 
     *             nValue 具体结点的数值
     *  返回值 
     *          BinaryTreeNode<T>* 二叉树节点
      */
    virtual BinaryTreeNode<T>* Find(const T& nValue) const
    {
        return Find(Root(), nValue);
    }
    
    //////////////////////////////////////////////////////////////////////
    /*
     *  根据具体值从根节点查找元素
     *  参数 
     *          pTreeNode 开始查找的节点
     *             nValue 具体结点的数值
     *  返回值 
     *          BinaryTreeNode<T>* 二叉树节点
      */
    virtual BinaryTreeNode<T>* Find(BinaryTreeNode<T>* pTreeNode, const T& nValue)const
    {
        BinaryTreeNode<T>* pRetNode = NULL;

        //如果是根节点node
        if (pTreeNode != NULL)
        {
            if (pTreeNode->m_nValue == nValue)
            {
                pRetNode = pTreeNode;
            }
            else
            {
                //查找左子树
                if (pRetNode == NULL)
                {
                    //查找其左子树
                    pRetNode = Find(pTreeNode->m_pLeftNode);
                }

                //如果左子树没有找到,查找右子树
                if (pRetNode == NULL)
                {
                    pRetNode = Find(pTreeNode->m_pRightNode);
                }
            }
        }

        return pRetNode;
    }

    //////////////////////////////////////////////////////////////////////
    /*
     *  根据具体结点从根节点查找元素
     *  参数 
     *             nValue 具体结点的数值
     *  返回值 
     *          BinaryTreeNode<T>* 二叉树节点
      */
    virtual BinaryTreeNode<T>* Find(const BinaryTreeNode<T>* pObjNode) const
    {
        return Find(root(), dynamic_caset< BinaryTreeNode<T>* >(pObjNode));
    }

    //////////////////////////////////////////////////////////////////////
    /*
     *  基于结点的查找
     *  参数 
     *          pTreeNode 开始查找的节点
     *             nValue 具体结点的数值
     *  返回值 
     *          BinaryTreeNode<T>* 二叉树节点
      */
    virtual BinaryTreeNode<T>* Find(BinaryTreeNode<T>* pTreeNode, const BinaryTreeNode<T>* pObjNode)const
    {
        BinaryTreeNode<T>* pRetNode = NULL;
        if (pTreeNode != NULL)
        {
            //如果是根结点,则直接返回根结点
            if (pTreeNode == pObjNode)
            {
                pRetNode = pTreeNode;
            }
            else    //不是跟结点
            {
                //查找左结点
                if (pRetNode == NULL)
                {
                    pRetNode = Find(pTreeNode->m_pLeftNode);
                }

                //如果左结点没有找到,则直接找右结点
                if (pRetNode == NULL)
                {
                    pRetNode = Find(pTreeNode->m_pRightNode);
                }
            }
        }

        return pRetNode;
    }

    //////////////////////////////////////////////////////////////////////
    /*
     *  结点插入类型enum
      */
    enum BTInsertType
     {
         BTIT_ANY,
         BTIT_LEFT,
         BTIT_RIGHT
     };

    //////////////////////////////////////////////////////////////////////
    /*
     *  插入结点根据类型
     *  参数 
     *          pNewTreeNode 准备插入的新节点
     *             pTreeNode 具体结点
     *             type 具体的插入类型
     *  返回值 
     *          成功返回true 失败返回false
      */
     virtual bool Insert(BinaryTreeNode<T>* pNewTreeNode, BinaryTreeNode<T>* pTreeNode, BTInsertType type)
     {
         bool ret = true;

         if (type == BTInsertType::BTIT_ANY)    //插入位置为any
         {
             if (pTreeNode->m_pLeftNode == NULL)     //左结点为空则插入做结点
             {
                 pTreeNode->m_pLeftNode = pNewTreeNode;
             }
             else if (pTreeNode->m_pRightNode == NULL)    //右结点为空则插入右结点
             {
                 pTreeNode->m_pRightNode = pNewTreeNode;
             }
             else //如果左右结点都不为空,则插入失败
             {
                 ret = false;
             }
         }
         else if (type == BTInsertType::BTIT_LEFT)    //插入左结点
         {
             if (pTreeNode->m_pLeftNode == NULL)    //左结点为空则设置左结点
             {
                 pTreeNode->m_pLeftNode = pNewTreeNode;
             }
             else //不为空
             {
                 ret = false;
             }
         }
         else if (type == BTInsertType::BTIT_RIGHT)    //插入右结点
         {
             if (pTreeNode->m_pRightNode == NULL)    //右结点为空则设置右结点
             {
                 pTreeNode->m_pRightNode = pNewTreeNode;
             }
             else //不为空
             {
                 ret = false;
             }
         }
         else
         {
             ret = false;
         }

         return ret;
     }

     //////////////////////////////////////////////////////////////////////
    /*
     *  插入新结点,没有位置要求
     *  参数 
     *          pNewTreeNode 准备插入的新节点
     *  返回值 
     *          成功返回true 失败返回false
      */
     virtual bool Insert(BinaryTreeNode<T>* pNewTreeNode)
     {
         return Insert(dynamic_caset< BinaryTreeNode<T>* >(pNewTreeNode), BTInsertType::BTIT_ANY);
     }

     //////////////////////////////////////////////////////////////////////
    /*
     *  插入结点,指定插入位置
     *  参数 
     *          pNewTreeNode 准备插入的新节点
     *             pTreeNode 具体结点
     *             type 具体的插入类型
     *  返回值 
     *          成功返回true 失败返回false
      */
     virtual bool Insert(BinaryTreeNode<T>* pTreeNode, BTInsertType type)
     {
         bool ret = true;

         if (pTreeNode != NULL)
         {
             if (pTreeNode->m_pRoot == NULL)
             {
                 pTreeNode->m_pParentNode = pTreeNode;
             }
             else
             {
                 BinaryTreeNode<T>* pNode = Find(pTreeNode->m_pParentNode);
                 if (pNode != NULL)
                 {
                     ret = Insert(dynamic_caset<BinaryTreeNode<T>*>(pTreeNode), pNode, type);
                 }
                 else 
                 {
                     LOGERROR("Parameter invalid...");
                 }
             }
         }
         else 
         {
             LOGERROR("Parameter invalid...");
         }

         return ret;
     }

    //////////////////////////////////////////////////////////////////////
    /*
     *  插入结点,指定插入位置和父节点
     *  参数 
     *          nValue 插入的值
     *             pParentTreeNode 父结点
     *             type 插入类型
     *  返回值 
     *          成功返回true 失败返回false
      */
     virtual bool Insert(const T& nValue, BinaryTreeNode<T>* pParentTreeNode, BTInsertType type)
     {
         bool ret = true;
        BinaryTreeNode<T>* pNewTreeNode = BinaryTreeNode<T>::CreateNew();
        if (pNewTreeNode != NULL)
        {
            pNewTreeNode->m_pParentNode = pParentTreeNode;
            pNewTreeNode->m_nValue = nValue;
            ret = Insert(pNewTreeNode, type);
            if (!ret)
            {
                SAFE_RELEASE(pNewTreeNode);
            }
        }
        else
        {
            LOGERROR("No enough memory...");
        }

         return ret;
     }

     //////////////////////////////////////////////////////////////////////
    /*
     *  插入结点,指定父节点
     *  参数 
     *          nValue 插入的值
     *             pParentTreeNode 父结点
     *             type 插入类型
     *  返回值 
     *          成功返回true 失败返回false
      */
     virtual bool Insert(const T& nValue, BinaryTreeNode<T>* pParentTreeNode)
     {
         return Insert(nValue, pParentTreeNode, BTInsertType::BTIT_ANY);
     }

     //////////////////////////////////////////////////////////////////////
    /*
     *  删除结点
     *  参数 
     *          pDelTreeNode 待删除的结点
     *             pRetTreeNode 父结点
     *             type 插入类型
     *  返回值 
     *          无
      */
     virtual void Remove(BinaryTreeNode<T>* pDelTreeNode, BinaryTreeNode<T>* pRetTreeNode)
     {
         pRetTreeNode = new BTree<T>();
         if (!pRetTreeNode)
         {
             LOGERROR("No enough memory...");
             return false;
         }
         else
         {
             if (pDelTreeNode == Root())
             {
                 this->m_pRoot = NULL;
             }
             else
             {
                 BinaryTreeNode<T>* pParentTreeNode = dynamic_caset<BinaryTreeNode<T>*>(pDelTreeNode->m_pParentNode);
                 if (pParentTreeNode && pParentTreeNode->m_pLeftNode == pDelTreeNode)
                 {
                     pParentTreeNode->m_pLeftNode = NULL;
                 }
                 else if (pParentTreeNode && pParentTreeNode->m_pLeftNode == pDelTreeNode)
                 {
                     pParentTreeNode->m_pRightNode = NULL;
                 }

                 pDelTreeNode->m_pParentNode = NULL;
             }

            pRetTreeNode->m_pRoot = pDelTreeNode;
         }
     }

     //////////////////////////////////////////////////////////////////////
    /*
     *  根据值删除结点
     *  参数 
     *          nValue 值
     *  返回值 
     *          BTree<T>*
      */
     virtual BTree<T>* Remove(const T& nValue)
     {
         BTree<T>* ret = NULL;
         BinaryTreeNode<T>* pTreeNode = Find(nValue);
         if (pTreeNode == NULL)
         {
             LOGERROR("No value...");
         }
         else
         {
             Remove(pTreeNode, ret);
         }
         return ret;
     }

    //////////////////////////////////////////////////////////////////////
    /*
     *  根据结点删除
     *  参数 
     *          pTreeNode 待删除的结点
     *  返回值 
     *          BTree<T>*
      */
     virtual BTree<T>* Remove(BinaryTreeNode<T>* pTreeNode)
     {
         BTree<T>* ret = NULL;
         BinaryTreeNode<T>* pTreeNode = Find(nValue);
         if (pTreeNode == NULL)
         {
             LOGERROR("No value...");
         }
         else
         {
             Remove(dynamic_caset<BinaryTreeNode<T>*>(pTreeNode), ret);
         }
         return ret;
     }    
}

 总结

 最近时间稍微充裕了一点,所以整理的一些二叉树相关的算法,算法资料和思想,如有错误,欢迎指正!后续如果有新的算法,我也会更新进去

猜你喜欢

转载自blog.csdn.net/Windgs_YF/article/details/86520530