数据结构——二叉树的基本操作

二叉树节点结构

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

    T _data;
    BinaryTreeNode<T>* _pLeft;
    BinaryTreeNode<T>* _pRight;
};

二叉树的构造

template<class T>
class BinaryTree
{
    typedef BinaryTreeNode<T> Node;
public:
    //构造函数
    BinaryTree()
        :_pRoot(NULL)
    {}

    BinaryTree(const T array[], size_t size, const T& invalid)
    {
        size_t index = 0;
        _CreateTree(_pRoot, array, size, index, invalid);
    }

    //拷贝构造函数
    BinaryTree(const BinaryTree<T>& t)
    {
        _pRoot = _CopyBinaryTree(t._pRoot );
    }

    //赋值运算符重载
    BinaryTree<T>& operator=(const BinaryTree<T>& t)
    {
        //先销毁当前对象,再拷贝
        _DestroyTree(t._pRoot );
        _CopyBinaryTree(t._pRoot );
    }
    ~BinaryTree()
    {
        _DestroyTree(_pRoot);
    }
    private:
    void _CreateTree(Node*& pRoot, const T array[], size_t size, size_t& index, const T& invalid)
    {
        if(index < size&&array[index] != invalid)
        {
            pRoot = new Node(array[index]);
            _CreateTree(pRoot->_pLeft ,array,size,++index,invalid);
            _CreateTree(pRoot->_pRight ,array,size,++index,invalid);
        }
    }

    Node* _CopyBinaryTree(Node* pRoot)
    {
        if(NULL != pRoot)
        {
            Node* pNew = new Node(pRoot->_data);
            pNew->_pLeft = _CopyBinaryTree(pRoot->_pLeft );
            pNew->_pRight = _CopyBinaryTree(pRoot->_pRight );
            return pNew;
        }
        return NULL;
    }
    void _DestroyTree(Node* pRoot)
    {
        if(pRoot)
        {
            _DestroyTree(pRoot->_pLeft );
            _DestroyTree(pRoot->_pRight );
            delete pRoot;
            pRoot = NULL;
        }
    }
private:
    BinaryTreeNode<T>* _pRoot;
};

二叉树遍历——递归

public:
    // 先序遍历——递归
    void PreOrder()
    {
        cout<<"PreOrder()"<<endl;
        _PreOrder(_pRoot);
        cout<<endl;
    }

    // 中序遍历——递归
    void InOrder()
    {
        cout<<"InOrder()"<<endl;
        _InOrder(_pRoot);
        cout<<endl;
    }
        // 后续遍历——递归
    void PostOrder()
    {
        cout<<"PostOrder()"<<endl;
        _PostOrder(_pRoot);
        cout<<endl;
    }
private:
    void _PreOrder(Node* pRoot)
    {
        if(pRoot)
        {
            cout<<pRoot->_data <<" ";
            _PreOrder(pRoot->_pLeft );
            _PreOrder(pRoot->_pRight );
        }
    }
    void _InOrder(Node* pRoot)
    {
        if(pRoot)
        {
            _InOrder(pRoot->_pLeft );
            cout<<pRoot->_data <<" ";
            _InOrder(pRoot->_pRight );
        }
    }
    void _PostOrder(Node* pRoot)
    {
        if(pRoot)
        {
            _PostOrder(pRoot->_pLeft );
            _PostOrder(pRoot->_pRight );
            cout<<pRoot->_data <<" ";
        }
    }

二叉树遍历——非递归

//先序遍历
    void _PreOrder_Nor(Node* pRoot)
    {
        if(pRoot)
        {
            stack<Node*> s;
            Node* pCur = pRoot;
            s.push(pCur);
            while(!s.empty())
            {
                pCur = s.top();
                cout<<pCur->_data <<" ";
                s.pop();
                if(pCur->_pRight )
                    s.push(pCur->_pRight );
                if(pCur->_pLeft )
                    s.push(pCur->_pLeft );
            }
        }
    }
//中序遍历
    void _InOrder_Nor(Node* pRoot)
    {
        stack<Node*> s;
        Node* pCur = pRoot;
        while(pCur || !s.empty())
        {
            while(pCur)
            {
                s.push(pCur);
                pCur = pCur->_pLeft ;
            }
            pCur = s.top();
            cout<<pCur->_data <<" ";
            s.pop();
            pCur = pCur->_pRight ;
            //while(NULL == pCur->_pRight )
            //{
            //  pCur = s.top();
            //  cout<<pCur->_data <<" ";
            //  s.pop();
            //}
            //pCur = pCur->_pRight ;
        }
    }
//后序遍历

    void _PostOrder_Nor(Node* pRoot)
    {
        stack<Node*> s;
        Node* pCur = pRoot;//指向根节点
        Node* pPre = NULL;//指向已经访问过的节点
        Node* pTop = NULL;//指向栈顶节点
        while(pCur || !s.empty())
        {
            while(pCur)
            {
                s.push(pCur);
                pCur = pCur->_pLeft ;
            }
            pTop = s.top();
            //当节点右子树为空或当前右节点已经访问过,则对该节点进行访问
            if(pTop->_pRight == NULL || pPre == pTop->_pRight )
            {
                cout<<pTop->_data <<" ";
                pPre = pTop;
                s.pop();
            }
            //转换为子问题
            else
                pCur = pTop->_pRight ;
            //注意是pCur是指向栈顶节点的右节点
        }
    }

二叉树层序遍历

// 层序遍历
    void LevelOrder()
    {
        cout<<" LevelOrder()"<<endl;
        queue<Node*> q;//申请一个保存二叉树节点的队列
        Node* pCur = NULL;
        if(NULL != _pRoot)
        {
            q.push (_pRoot);
            while(!q.empty ())
            {
                pCur = q.front ();
                cout<<pCur->_data <<" ";

                if(pCur->_pLeft )
                    q.push (pCur->_pLeft );
                if(pCur->_pRight )
                    q.push (pCur->_pRight );
                q.pop ();
            }
        }
        cout<<endl;
    }

二叉树面试题
求镜像二叉树

public:
    //求某一二叉树的镜像——递归
    void GetBinaryMirror()
    {
        _GetBinaryMirror(_pRoot);
    }
    //求某一二叉树的镜像——非递归
    void GetBinaryMirror_Nor()
    {
        _GetBinaryMirror_Nor(_pRoot);
    }
        void _GetBinaryMirror(Node* pRoot)
    {
        if(pRoot)
        {
            std::swap (pRoot->_pLeft ,pRoot->_pRight );
            _GetBinaryMirror(pRoot->_pLeft );
            _GetBinaryMirror(pRoot->_pRight );
        }
    }

private:
    void _GetBinaryMirror_Nor(Node* pRoot)
    {
        queue<Node*> q;
        q.push(pRoot);
        while(!q.empty())
        {
            Node* pCur = q.front();
            std::swap (pCur->_pLeft ,pCur->_pRight );
            if(pCur->_pLeft )
                q.push(pCur->_pLeft );
            if(pCur->_pRight )
                q.push(pCur->_pRight );
            q.pop();
        }
    }

判断一棵树是不是完全二叉树

    //判断一颗树是否为完全二叉树
    bool IsCompleteBinaryTree()
    {
        bool flag = true;//判断一棵子树是否为一棵二叉树的标记
        queue<Node*> q;//运用队列进行层序遍历
        q.push(_pRoot);
        while(!q.empty())
        {
            Node* pCur = q.front();
            q.pop();
            //如果队首元素的左子树为空将标记置为false如果层序遍历后面的节点还有子树说明不是
            if(NULL == pCur->_pLeft )
                flag = false;
            else
            {
                //如果falg为假,说明之前已经有节点的孩子为空,又因当前节点的左孩子不为空,说明不是
                if(flag == false)
                    return false;
                q.push(pCur->_pLeft );
            }
            //如果队首元素的右树为空,将标记置为false如果层序遍历后面的节点还有子树,说明不是
            if(NULL == pCur->_pRight )
                flag = false;
            else
            {
                //如果flag为假说明之前已经有节点的孩子为空,又因当前节点的右孩子不为空说明不是
                if(flag == false)
                    return false;
                q.push(pCur->_pRight );
            }
        }
        return true;
    }
public:
    //找双亲节点
    Node* GetParent(T& value)
    {
        Node* x = Find(value);
        return _GetParent(_pRoot,x);
    }

private:    
    Node* _GetParent(Node* pRoot,Node* x)
    {
        if(pRoot == NULL||x == NULL||pRoot == x)
            return NULL;
        if(x == pRoot->_pLeft || x == pRoot->_pRight )
            return pRoot;
        Node* pLeft = _GetParent(pRoot->_pLeft ,x);
        Node* pRight = _GetParent(pRoot->_pRight ,x);
    }
public:
    //判断某节点是否存在
    Node* Find(const T& value)
    {
        return _Find(_pRoot,value);
    }
private:
    Node* _Find(Node* pRoot,const T& value)
    {
        if(NULL == pRoot)
            return NULL;
        if(pRoot->_data == value)
            return pRoot;
        Node* pCur = _Find(pRoot->_pLeft ,value);
        if(pCur)
            return pCur;
        return _Find(pRoot->_pRight ,value);
    }
    //获得某节点的左孩子
    Node* GetLeftChild(Node* pCur)
    {
        return (NULL == pCur)?NULL:pCur->_pLeft ;
    }

    //获得某节点的右孩子
    Node* GetRightChild(Node* pCur)
    {
        return (NULL == pCur)?NULL:pCur->_pRight ;
    }
    //计算二叉树的高度
    size_t Height()
    {
        return _Height(_pRoot);
    }
    size_t _Height(Node* pRoot)
    {
        if(NULL == pRoot)
            return 0;
        if(NULL == pRoot->_pLeft && NULL == pRoot->_pRight )
            return 1;
        size_t hLeft = _Height(pRoot->_pLeft );
        size_t hRight = _Height(pRoot->_pRight );
        return hLeft>hRight?hLeft+1:hRight+1;
    }

    //计算叶子节点的个数
    size_t GetLeafNode()
    {
        return _GetLeafNode(_pRoot);
    }
    size_t _GetLeafNode(Node* pRoot)
    {
        if(NULL == pRoot)
            return 0;
        if(NULL == pRoot->_pLeft && NULL == pRoot->_pRight )
            return 1;
        return _GetLeafNode(pRoot->_pLeft )+_GetLeafNode(pRoot->_pRight );
    }
    //计算第K层的节点数
    size_t GetKLevelNode(size_t k)
    {
        return _GetKLevelNode(_pRoot, k);
    }

    size_t _GetKLevelNode(Node* pRoot,size_t k)
    {
        if(NULL == pRoot && k<1 && k>_Height(pRoot))
            return 0;
        if(k == 1)
            return 1;
        size_t kLeft = _GetKLevelNode(pRoot->_pLeft ,k-1);
        size_t kRight = _GetKLevelNode(pRoot->_pRight ,k-1);
        return kLeft + kRight;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值