二叉树的创建及一些基本操作

本文介绍了一个通用的二叉树模板类的实现方法,包括构造、遍历、查询等核心功能,并提供了多种遍历方式的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

.hpp

#define _CRT_SECURE_NO_WARNINGS 1
#pragma once

#include<iostream>
using namespace std;
#include<assert.h>
#include<stack>
#include<queue>

template<class T>
struct BinaryTreeNode
{
    BinaryTreeNode(const T& data)
    :_left(NULL)
    , _right(NULL)
    , _data(data)
    {}

    BinaryTreeNode* _left;//左指针域
    BinaryTreeNode* _right;//右指针域
    T _data;//数据域
};

template<class T>
class BinaryTree
{
    typedef BinaryTreeNode<T> Node;

public:
    BinaryTree()
        :_pRoot(NULL)
    {}
    //构造
    BinaryTree(T* arr, size_t size)
    {
        assert(arr);
        size_t index = 0;
        _CreateBinaryTree(_pRoot,arr,size,index);
    }
    //拷贝构造
    BinaryTree(const BinaryTree<T>& bt)
    {
        _pRoot=_CopyBinaryTree(bt._pRoot);
    }
    //赋值操作符重载
    BinaryTree& operator =(const BinaryTree<T>& bt)
    {
        if (this != &bt)
        {
            _DestroyTree(_pRoot);
            _CopyBinaryTree(bt._pRoot);
        }
        return *this;
    }
    //简洁版的写法
    BinaryTree& operator =(BinaryTree<T> bt)
    {
        std::swap(_pRoot, bt._pRoot);//缺点是不能避免自己跟自己赋值
        return *this;
    }
    //析构函数
    ~BinaryTree()
    {
        if (_pRoot)
        {
            _DestroyTree(_pRoot);
            _pRoot = NULL;
        }
    }
public:
    //前序遍历(递归)
    void PrevOrder()
    {
        cout << "前序遍历" << ": ";
        _PrevOrder(_pRoot);
        cout << endl;
    }
    //中序遍历(递归)
    void InOrder()
    {
        cout << "中序遍历" << ": ";
        _InOrder(_pRoot);
        cout << endl;
    }

    //后序遍历(递归)
    void PostOrder()
    {
        cout << "后序遍历" << " ";
        _PostOrder(_pRoot);
        cout << endl;
    }

    //层序遍历
    void LevelOrder()
    {
        _LevelOrder(_pRoot);
    }

    //求树的深度
    void Height()
    {
        cout << "树的深度" << " : ";
        cout << _Height(_pRoot) << endl;;
    }

    //求叶子节点的个数
    void GetLeefCount()
    {
        cout << "叶子结点的个数:";
        cout << _GetLeefCount(_pRoot) << endl;
    }

    //求第K层结点的个数
    void GetKLevelNodeCount(size_t k)
    {
        cout << "第k层结点的个数:"<<" ";
        if (k  > _Height(_pRoot))
        {
            cout << "0" << endl;
            return;
        }
        cout << _GetKLevelNodeCount(_pRoot, k) << endl;
    }

    // 值为data的结点是否存在 
    Node* Find(const T& data)
    {
        return _Find(_pRoot, data);
    }

    //求pNode的双亲
    Node* GetParent(Node* pNode)
    {
        return _GetParent(_pRoot, pNode);
    }

    //求一棵树一共有多少结点
    void GetTreeNodeCount()
    {
        cout << "树的总结点数:" << " ";
        cout << _GetTreeNodeCount(_pRoot) << endl;
    }

    //判断一个结点在不在树中
    bool IsNodeInTree(Node* pNode)
    {
        return _IsNodeInTree(_pRoot, pNode);
    }

    // 获取二叉树的左孩子 
    Node* GetLeftChild(Node* pCur)
    {
        return pCur->_left;
    }

    // 获取二叉树的右孩子 
    Node* GetRightChild(Node* pCur)
    {
        return pCur->_right;
    }
protected:
    //构造的实现
    void _CreateBinaryTree(Node*& pRoot, T* arr, size_t size, size_t& index)
    {
        if ((index < size) && ('#' != arr[index]))
        {
            pRoot = new Node(arr[index]);
            _CreateBinaryTree(pRoot->_left, arr, size, ++index);
            _CreateBinaryTree(pRoot->_right, arr, size, ++index);
        }
    }
    //拷贝构造实现
    Node* _CopyBinaryTree(Node* pRoot)
    {
        if (NULL == pRoot)
            return NULL;
        Node* _pRoot = new Node(pRoot->_data);
        _pRoot->_left = _CopyBinaryTree(pRoot->_left);
        _pRoot->_right = _CopyBinaryTree(pRoot->_right);
        return _pRoot;
    }
    //销毁函数
    void _DestroyTree(Node*& pRoot)
    {
        if (NULL == pRoot)//如果根结点为空,不需要释放,直接返回
            return;

       _DestroyTree(pRoot->_left);
       _DestroyTree(pRoot->_right);
       delete pRoot;
       pRoot = NULL;
    }
    //前序遍历(递归)实现方法
    void _PrevOrder(Node*& pRoot)
    {
        if (NULL == pRoot)
            return;
        cout << pRoot->_data << " ";
        _PrevOrder(pRoot->_left);
        _PrevOrder(pRoot->_right);
    }
    //前序遍历(循环)实现方法
    void _PrevOrder(Node*& pRoot)
    {
        stack<Node*> s1;
        if (pRoot)
            s1.push(pRoot);

        while (!s1.empty())
        {
            Node* cur = s1.top();

            s1.pop();

            if (cur->_right)
                s1.push(cur->_right);

            if (cur->_left)
                s1.push(cur->_left);

            cout << cur->_data << " ";
        }
    }
    //中序遍历(递归)实现方法
    void _InOrder(Node*& pRoot)
    {
        if (NULL == pRoot)
            return;
        _InOrder(pRoot->_left);
        cout << pRoot->_data << " "; 
        _InOrder(pRoot->_right);
    }
    //中序遍历(循环)实现方法
    void _InOrder(Node*& pRoot)
    {
        stack<Node*> s;
        Node* cur = pRoot;
        while (NULL != cur || !s.empty())//判断条件是关键点
        {
            while (NULL != cur)
            {
                s.push(cur);
                cur = cur->_left;
            }

            Node* node = s.top();
            s.pop();

            cout << node->_data << " ";
            cur = node->_right;
        }
    }
    //后续遍历(递归)实现方法
    void _PostOrder(Node*& pRoot)
    {
        if (NULL == pRoot)
            return;
        _PostOrder(pRoot->_left);
        _PostOrder(pRoot->_right);
        cout << pRoot->_data << " ";
    }
    //后续遍历(循环)实现方法
    void _PostOrder(Node*& pRoot)
    {
        stack<Node*> s1;
        stack<Node*> s2;
        if (pRoot)
            s1.push(pRoot);

        Node* prev = NULL;
        while (!s1.empty())
        {
            Node* cur = s1.top();
            while (!s1.empty())
            {
                Node* cur = s1.top();
                s1.pop();
                s2.push(cur);
                if (cur->_left)
                    s1.push(cur->_left);

                if (cur->_right)
                    s1.push(cur->_right);
            }

            while (!s2.empty())
            {
                Node* tmp = s2.top();
                cout << tmp->_data << " ";
                s2.pop();
            }
        }
    }
    //层序遍历树
    void _LevelOrder(Node*& pRoot)
    {
        queue<Node*> q;
        if (NULL != pRoot)
            q.push(pRoot);
        while (NULL != pRoot)
        {
            pRoot = q.front();
            if (NULL != pRoot->_left)
                q.push(pRoot->_left);

            if (NULL != pRoot->_right)
                q.push(pRoot->_right);

            cout <<q.front()->_data<< " ";

            q.pop();
            if (q.empty())
                pRoot = NULL;
        }
        cout << endl;
    }
    //求高度实现实现方法
    size_t _Height(Node*& pRoot)
    {
        if (NULL == pRoot)
            return 0;

        return (((_Height(pRoot->_left))>(_Height(pRoot->_right))) ? (_Height(pRoot->_left) + 1):(_Height(pRoot->_right)+1));
    }
    //求也只结点的个数
    size_t _GetLeefCount(Node*& pRoot)
    {
        if (NULL == pRoot)
            return 0;

        if (NULL == pRoot->_left && NULL == pRoot->_right)
            return 1;

        return (_GetLeefCount(pRoot->_left) + _GetLeefCount(pRoot->_right));
    }
    //求第K层结点的个数
    size_t _GetKLevelNodeCount(Node*& pRoot,size_t k)
    {
        if (NULL == pRoot || k < 1)
            return 0;

        if (1 == k)
            return 1;

        //可以划分成K-1层,左 + 右孩子的个数
        size_t Leftcount = _GetKLevelNodeCount(pRoot->_left, k - 1);
        size_t Rightcount = _GetKLevelNodeCount(pRoot->_right, k - 1);

        return Leftcount + Rightcount;
    }
    //查找一个值为data的元素是不是在树里面
    Node* _Find(Node* pRoot, const T& data)
    {
        if (NULL == pRoot)
            return NULL;

        if (pRoot->_data == data)
            return pRoot;

        Node* cur = _Find(pRoot->_left, data);
        if (cur)
            return cur;

        return _Find(pRoot->_right, data);
    }
    //求pNode的双亲
    Node* _GetParent(Node* pRoot, Node* pNode)
    {
        if (NULL == pRoot || NULL == pNode)
            return NULL;

        if (pRoot->_left == pNode || pRoot->_right == pNode)
            return pRoot;

        Node* cur = _GetParent(pRoot->_left, pNode);
        if (cur)
            return cur;

        return _GetParent(pRoot->_right, pNode);
    }
    //求二叉树中总结点的个数
    size_t _GetTreeNodeCount(Node* pRoot)
    {
        if (NULL == pRoot)
            return 0;

        if (NULL == pRoot->_left && NULL == pRoot->_right)
            return 1;

        return _GetTreeNodeCount(pRoot->_left) + _GetTreeNodeCount(pRoot->_right)+1;
    }
    //判断一个结点在不在树中
    bool _IsNodeInTree(Node*& pRoot,Node* pNode)
    {
        if (NULL == pRoot || NULL == pNode)
            return false;

        if (pNode == pRoot)
            return true;

         bool cur = _IsNodeInTree(pRoot->_left, pNode);
        if (cur)
            return true;

        return _IsNodeInTree(pRoot->_right, pNode);
    }

protected:
    Node* _pRoot;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值