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

来源:互联网 发布:java redis 获取list 编辑:程序博客网 时间:2024/05/04 10:19

二叉树节点结构

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;    }