二叉树的简单操作(c++实现)

什么是二叉树?
一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上两棵分别称为左子树和右子树的二叉树组成
二叉树的特点
1.每个结点最多有两棵子树,即二叉树不存在度大于2的结点(分支最大不超过2)
2.二叉树的子树有左右之分,其子树的次序不能颠倒
这里写图片描述

下面来介绍两种特殊的二叉树
这里写图片描述
1.满二叉树:在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子结点都在同一层
2.完全二叉树:如果一棵具有N个节点的二叉树的结构与满二叉树的前N个结点的结构相同,即就称为完全二叉树
二叉树的性质
1.若规定根节点的层数为1,则一棵非空二叉树的第i层上最多有2^(i-1)(i>=1)个结点
2.若规定只有根节点的二叉树的深度为1,则深度为K的二叉树的最大结点数是2^k-1(k>=0)
3.对于任何一棵二叉树,如果其叶子结点个数为n0,度为2的非叶子结点个数为n2,则n0=n2+1
4.具有n个结点的完全二叉树的深度k为log2(n+1)上取整(用性质2逆推)
5.对于具有n个结点的完全二叉树,如果按照从上至下从左至右的顺序对所有结点进行编号,则对于序号为i的结点有:
a:如果i>0,则序号为i结点的双亲结点的序号为(i-1)/2;
如果i=0,则序号为i的结点为根节点,无双亲结点
b:如果2i+1

#include<iostream>
#include<queue>
#include<stack>
#include<string.h>
using namespace std;
//孩子表示法
template<class T>
struct BinTreeNode
{

    BinTreeNode<T>* _lChild;//左孩子
    BinTreeNode<T>* _rChild;//右孩子
    T _data;//结点数据
    BinTreeNode(const T& data)
        :_lChild(NULL)
        , _rChild(NULL)
        , _data(data)
    {}
};
template<class T>
class BinTree
{

public:
    typedef BinTreeNode<T> Node;
    typedef BinTreeNode<T>* pNode;
    BinTree()//构造函数
        :_pRoot(NULL)
    {}
    BinTree(const T* array, size_t size, const T& invalid)
    {
        size_t index = 0;
        CreateBinTree(_pRoot, array, size, index, invalid);//创建树
    }
    BinTree(const BinTree<T>& bt)//拷贝构造函数
    {
        _pRoot = CopyBinTree(bt._pRoot);
    }
    BinTree<T>& operator=(const BinTree<T>& bt)//赋值运算符重载
    {
        if (this != &bt)
        {
            DestroyBinTree(_pRoot);
            _pRoot = CopyBinTree(bt._pRoot);
        }
        return *this;
    }
    ~BinTree()//析构函数
    {
        DestroyBinTree(_pRoot);
    }
    void PreOrder()//递归前序遍历
    {
        cout << "PreOrder: ";
        _PreOrder(_pRoot);
        cout << endl;
    }
    void PreOrder_Nor1()//非递归前序遍历1
    {
        cout << "PreOrder_Nor1: ";
        _PreOrder_Nor1(_pRoot);
        cout << endl;
    }
    void PreOrder_Nor2()//非递归前序遍历2
    {
        cout << "PreOrder_Nor2: ";
        _PreOrder_Nor2(_pRoot);
        cout << endl;
    }
    void MidOrder()//递归中序遍历
    {
        cout << "MidOrder: ";
        _MidOrder(_pRoot);
        cout << endl;
    }
    void MidOrder_Nor()//非递归中序遍历
    {
        cout << "MidOrder_Nor: ";
        _MidOrder_Nor(_pRoot);
        cout << endl;
    }
    void PostOrder()//递归后序遍历
    {
        cout << "PostOrder: ";
        _PostOrder(_pRoot);
        cout << endl;
    }
    void PostOrder_Nor()//非递归后序遍历
    {
        cout << "PostOrder_Nor: ";
        _PostOrder_Nor(_pRoot);
        cout << endl;
    }
    void LevelOrder()//层序遍历
    {
        cout << "LevelOrder: " ;
        _LevelOrder(_pRoot);
        cout << endl;
    }
    size_t Size()//节点的个数
    {
        return _Size(_pRoot);
    }
    size_t LeefSize()//求叶节点的个数
    {
        return _LeefSize(_pRoot);
    }
    size_t Height() //树的高度
    {
        return _Height(_pRoot);
    }
    pNode Find(const T&data)//查找树的某个节点
    {
        return _Find(_pRoot,data);
    }
    pNode Parent(pNode node)//找节点的双亲
    {
        return _Parent(_pRoot,node);
    }
    pNode lChild(pNode node)//找节点的左孩子
    {
        return (node == NULL) ? NULL : node->_lChild;
    }
    pNode rChild(pNode node)//找节点的右孩子
    {
        return (node == NULL) ? NULL : node->_rChild;
    }
    size_t GetKChild(size_t K)//树的第K层有多少节点
    {
        return _GetKChild(_pRoot, K);
    }
    void MirrorBinTree()//二叉树的镜像
    {
        cout << "MirrorBinTree: ";
        return _MirrorBinTree(_pRoot);
        cout << endl;
    }
    //判断二叉树是否为满树
    bool IsComBinTree()
    {
        return _IsComBinTree(_pRoot);
    }
private:
    void CreateBinTree(pNode& pRoot, const T* array,
        size_t size, size_t& index, const T& invalid)
    {
        if (index < size&&'#' != array[index])
        {
            //创建根节点
            pRoot = new Node(array[index]);
            //创建左子树
            CreateBinTree(pRoot->_lChild, array, size, ++index, invalid);
            //创建右子树
            CreateBinTree(pRoot->_rChild, array, size, ++index, invalid);
        }
    }
    pNode CopyBinTree(pNode pRoot)
    {
        pNode pNewRoot = NULL;
        if (pRoot)
        {
            //拷贝根节点
            pNewRoot = new Node(pRoot->_data);
            //拷贝根节点的左子树
            if (pRoot->_lChild)
                pNewRoot->_lChild = CopyBinTree(pRoot->_lChild);
            //拷贝根节点的右子树
            if (pRoot->_rChild)
                pNewRoot->_rChild = CopyBinTree(pRoot->_rChild);
        }
        return pNewRoot;
    }
    void DestroyBinTree(pNode pRoot)
    {
        if (pRoot)
        {
            DestroyBinTree(pRoot->_lChild);
            DestroyBinTree(pRoot->_rChild);
            delete pRoot;
            pRoot = NULL;
        }
    }
    //前序遍历(根+左子树+右子树)-->递归实现
    void _PreOrder(pNode& pRoot)
    {
        if (pRoot)
        {
            cout << pRoot->_data << " ";
            _PreOrder(pRoot->_lChild);
            _PreOrder(pRoot->_rChild);
        }
    }
    //前序遍历-->非递归实现1
    //将左右子树都压进栈中,先压右栈,再压左栈
    void _PreOrder_Nor1(pNode pRoot)
    {
        if (pRoot == NULL)
        {
            return;
        }
        stack<pNode> s;
        pNode cur = pRoot;
        s.push(cur);
        while (!s.empty())
        {
            cur = s.top();
            cout << cur->_data << " ";
            s.pop();
            if (cur->_rChild&&cur->_rChild->_data != '#')
            {
                s.push(cur->_rChild);
            }
            if (cur->_lChild&&cur->_lChild ->_data!= '#')
            {
                s.push(cur->_lChild);
            }
        }
    }
    //前序遍历-->非递归实现2
    //只将左子树压进栈中
    void _PreOrder_Nor2(pNode pRoot)
    {
        stack<pNode> s;
        s.push(pRoot);
        while (!s.empty())
        {
            pNode cur = s.top();
            s.pop();
            while (cur)
            {
                cout << cur->_data << " ";
                if (cur->_rChild)
                    s.push(cur->_rChild);
                cur = cur->_lChild;
            }
        }
    }
    //中序遍历(左子树+根+右子树)--->递归实现
    void _MidOrder(pNode& pRoot)
    {
        if (pRoot)
        {
            _MidOrder(pRoot ->_lChild);
            cout << pRoot->_data << " ";
            _MidOrder(pRoot->_rChild);
        }
    }
    //中序遍历-->非递归实现
    void _MidOrder_Nor(pNode pRoot)
    {
        stack<pNode>s;
        pNode cur = pRoot;
        while (cur||!s.empty())
        {
            while (cur)
            {
                s.push(cur);
                cur=cur->_lChild;
            }
            cur = s.top();
            s.pop();
            cout << cur->_data <<" ";
            if (cur->_rChild)
            {
                cur = cur->_rChild;
            }
            else
            {
                cur = NULL;
            }
        }
    }
    //后序遍历(左子树+右子树+根)-->递归实现
    void _PostOrder(pNode& pRoot)
    {
        if (pRoot)
        {
            _PostOrder(pRoot->_lChild);
            _PostOrder(pRoot->_rChild);
            cout << pRoot->_data << " ";
        }
    }
    //后序遍历-->非递归实现
    void _PostOrder_Nor(pNode& pRoot)
    {
        stack<pNode> s;
        pNode cur = pRoot;
        pNode pPre = NULL;
        while (cur || !s.empty())
        {
            while (cur&&cur != pPre)
            {
                s.push(cur);
                cur = cur->_lChild;
            }
            if (s.empty())
                return;
            cur = s.top();
            if (cur->_rChild != NULL&&cur->_rChild != pPre)
            {
                cur = cur->_rChild;
            }
            else
            {
                cout << cur->_data << " ";
                s.pop();
                pPre = cur;
            }
        }
    }
    //层序遍历
    void _LevelOrder(pNode pRoot)
    {
        if (NULL == pRoot)//空树
            return;
        queue<pNode> qu;
        qu.push(pRoot);
        while (!qu.empty())
        {
            pNode pCur = qu.front();
            cout << pCur->_data << " ";
            if (pCur->_lChild)
                qu.push(pCur->_lChild);
            if (pCur->_rChild)
                qu.push(pCur->_rChild);
            qu.pop();
        }
        cout << endl;
    }
    //节点的个数
    size_t _Size(pNode pRoot)
    {
        if (NULL == pRoot)
            return 0;
        else
        {
            return _Size(pRoot->_lChild) + _Size(pRoot->_rChild) + 1;
        }
    }
    //叶节点的个数
    size_t _LeefSize(pNode pRoot)
    {
        if (NULL == pRoot)
            return 0;
        else if (NULL == pRoot->_lChild && NULL == pRoot->_rChild)
        {
            return 1;
        }
        else
            return _LeefSize(pRoot->_lChild) + _LeefSize(pRoot->_rChild);
    }
    size_t _Height(pNode pRoot)
    {
        if (NULL == pRoot)
            return 0;
        else if (NULL == pRoot->_lChild&&NULL == pRoot->_rChild)
            return 1;
        else
            return _Height(pRoot->_lChild) > _Height(pRoot->_rChild) ? 
            _Height(pRoot->_lChild) + 1: _Height(pRoot->_rChild) + 1;
    }
    pNode _Find(pNode pRoot, const T&data)//注意递归出口
    {
        pNode ret = NULL;
        if (NULL == pRoot)
            return NULL;
        else if (data == pRoot->_data)
            return pRoot;
        ret =  _Find(pRoot->_lChild, data);
        if (ret==NULL)
            ret =  _Find(pRoot->_rChild, data);
        return ret;
    }
    pNode _Parent(pNode pRoot, pNode node)//注意递归出口
    {
        pNode ret = NULL;
        if (NULL == pRoot || NULL == node || node == pRoot)
            return NULL;
        //验证根节点是不是双亲
        if (pRoot->_lChild == node || pRoot->_rChild == node)
            return pRoot;
        ret= _Parent(pRoot->_lChild, node);
        if (ret == NULL)
            ret= _Parent(pRoot->_rChild, node);
        return ret;
     }
    size_t _GetKChild(pNode pRoot, size_t K)
    {
        if (pRoot == NULL || K < 0)
            return 0;
        if (K == 1)
            return 1;
        return _GetKChild(pRoot->_lChild, K - 1) + _GetKChild(pRoot->_rChild, K - 1);
    }
    void _MirrorBinTree(pNode pRoot)
    {
        if (NULL == pRoot)
            return;
        if (pRoot)
        {
            swap(pRoot->_lChild, pRoot->_rChild);
            cout << pRoot->_data << " ";
        }
        _MirrorBinTree(pRoot->_lChild);
        _MirrorBinTree(pRoot->_rChild);
    }

private:
    pNode _pRoot;//节点类型的指针
};

测试代码:

void Test()
{
    char* pStr = "ABD###C#G";
    BinTree<char> bt1(pStr, strlen(pStr), '#');
    BinTree<char> bt2(bt1);
    bt2.PreOrder();
    bt2.PreOrder_Nor1();
    bt2.PreOrder_Nor2();
    bt2.MidOrder();
    bt2.MidOrder_Nor();
    bt2.PostOrder();
    bt2.PostOrder_Nor();
    bt2.LevelOrder();
    cout<<"Size= "<<bt2.Size()<<endl;
    cout << "LeefSize= " << bt2.LeefSize() << endl;
    cout << "Height= " << bt2.Height() << endl;
    cout << "Find= "<<(bt2.Find('D'))->_data << endl;
    cout << "Parent= " << bt2.Parent(bt2.Find('G'))->_data << endl;
    cout << "lChild= " << bt2.lChild(bt2.Find('B'))->_data << endl;
    cout << "rChild= " << bt2.rChild(bt2.Find('C'))->_data << endl;
    cout << "GetKChild= " << bt2.GetKChild(3) << endl;
    bt2.MirrorBinTree();
    cout << endl;

    char* pStr1 = "ABD##H##CF##G";
    BinTree<char> bt3(pStr1, strlen(pStr1), '#');
    if (bt3.IsComBinTree())
    {
        cout << "是完全二叉树" << endl;
    }
    else
    {
        cout << "不是完全二叉树" << endl;
    }
}
int main()
{
    Test();
    system("pause");
    return 0;
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值