递归类型的二叉树

来源:互联网 发布:mac删除下载的软件 编辑:程序博客网 时间:2024/05/22 16:58

1.创建节点结构体

template <class T>struct BinaryTreeNode//定义二叉树的节点{    BinaryTreeNode(const T& value)        :_value(value)        ,_pLeft(NULL)        ,_pRight(NULL)    {}    T _value;    BinaryTreeNode<T>* _pLeft;    BinaryTreeNode<T>* _pRight;};

2.创建一个类来表示二叉树

template<class T>class BinaryTree{    typedef BinaryTreeNode<T> Node;public:    BinaryTree()        :_pRoot(NULL)//根节点为空    {}    //构造函数    BinaryTree(const T arr[], size_t size, const T& invalid)    {        size_t index=0;        //创建树        _CreateBinaryTree(_pRoot, arr, size, index, invalid);    }};

3.创建树

private:    void _CreateBinaryTree(Node* &pRoot, const T arr[], size_t size, size_t& index, const T& invalid)    {        if(index<size && arr[index] != invalid)        {            //创建根节点            pRoot = new Node(arr[index]);            //创建左子树            _CreateBinaryTree(pRoot->_pLeft, arr, size, ++index, invalid);            //创建右子树            _CreateBinaryTree(pRoot->_pRight, arr, size, ++index, invalid);        }    }

用先序遍历的方式依次创建根节点—->创建左子树—–>创建右子树,
再分别将根节点的左子树和右子树作为根节点来创建新的树,最后就将整个树创建好了。
4.拷贝构造

public:    BinaryTree(const BinaryTree<T>& bt)    {        _pRoot = _CopyBinaryTree(bt._pRoot);    }private:    Node* _CopyBinaryTree(Node* pRoot)    {        Node* pNode = NULL;        if(pRoot)        {            pNode = new Node(pRoot->_value);            pNode->_pLeft = _CopyBinaryTree(pRoot->_pLeft);            pNode->_pRight = _CopyBinaryTree(pRoot->_pRight);        }        return pNode;    }

将_CopyBinaryTree()函数的权限设为private,是为了不被其他人看到。
5.赋值运算符重载

public:    BinaryTree<T>& operator=(const BinaryTree<T>& bt)    {        if(this != &bt)        {            _DestroyBinaryTree(_pRoot);            _pRoot = _CopyBinaryTree(bt._pRoot);        }        return *this;    }private:    Node* _CopyBinaryTree(Node* pRoot)    {        Node* pNode = NULL;        if(pRoot)        {            pNode = new Node(pRoot->_value);            pNode->_pLeft = _CopyBinaryTree(pRoot->_pLeft);            pNode->_pRight = _CopyBinaryTree(pRoot->_pRight);        }        return pNode;    }    void _DestroyBinaryTree(Node*& pRoot)    {        if(pRoot)        {            _DestroyBinaryTree(pRoot->_pLeft);            _DestroyBinaryTree(pRoot->_pRight);            delete pRoot;            pRoot = NULL;        }    }

删除原来的节点,要用后序遍历的方法,先删除左子树,再删除右子树,最后删除根节点。先序遍历和中序遍历在删除根节点后,就不能找到其左子树或者是右子树。
6.析构函数

public:    ~BinaryTree()    {        _DestroyBinaryTree(_pRoot);    }

7.三种遍历方式的打印
(1).先序遍历
根节点—->左子树—–>右子树

publicvoid PreOrder()    {        cout<<"PreOrder"<<endl;        _PreOrder(_pRoot);        cout<<endl;    }privatevoid _PreOrder(Node* pRoot)    {        if(pRoot)        {            cout<<pRoot->_value<<" ";            _PreOrder(pRoot->_pLeft);            _PreOrder(pRoot->_pRight);        }    }

(2).中序遍历
左子树—–>根节点—–>右子树

publicvoid InOrder()    {        cout<<"InOrder"<<endl;        _InOrder(_pRoot);        cout<<endl;    }privatevoid _InOrder(Node* pRoot)    {        if(pRoot)        {            _InOrder(pRoot->_pLeft);            cout<<pRoot->_value<<" ";            _InOrder(pRoot->_pRight);        }    }

(3).后序遍历
左子树—–>右子树—–>根节点

publicvoid PostOrder()    {        cout<<"PostOrder"<<endl;        _PostOrder(_pRoot);        cout<<endl;    }privatevoid _PostOrder(Node* pRoot)    {        if(pRoot)        {            _PostOrder(pRoot->_pLeft);            _PostOrder(pRoot->_pRight);            cout<<pRoot->_value<<" ";        }    }

8.层序遍历
层序遍历是按照树的结构,一层一层的访问,那么可以借助队列来完成。
先将根节点压入队列—->再读取队列的头结点—–>
再分别将读出的节点的左、右子树压入队列—–>读取当前节点的值—–>
再将头指针后移(将读过的结点pop出队列)。
具体的代码:

publicvoid LevelOrder()    {        cout<<"LevelOrder"<<endl;        _LevelOrder(_pRoot);        cout<<endl;    }privatevoid _LevelOrder(Node* pRoot)    {        if(pRoot == NULL)            return ;        queue<Node*> q;        q.push(pRoot);        while(!q.empty())        {            Node* temp = q.front();            if(temp->_pLeft)                q.push(temp->_pLeft);            if(temp->_pRight)                q.push(temp->_pRight);            cout<<temp->_value<<" ";            q.pop();        }    }

9.查找值为value的结点

public:    Node* Find(const T& value)    {        return _Find(_pRoot, value);    }private:    Node* _Find(Node* pRoot, const T& value)    {        if(pRoot == NULL)            return NULL;        if(pRoot->_value == value)            return pRoot;        Node* pNode = NULL;        if(pNode = _Find(pRoot->_pLeft, value))            return pNode;        return _Find(pRoot->_pRight, value);    }

先判断根节点是不是为空,再判断根节点是不是要查找的值,再遍历左子树、遍历右子树,直到找出。
10.查找左孩子、右孩子以及双亲节点

public:    Node* LeftChild()    {        return _pRoot->_pLeft;    }    Node* RightChild()    {        return _pRoot->_pRight;    }    Node* Parent(Node* pCur)    {        return _Parent(_pRoot, pCur);    }private:    Node* _Parent(Node* pRoot, Node* pCur)    {        assert(pCur != NULL || pRoot != NULL);        if(pCur == pRoot)            return NULL;        if(pCur == pRoot->_pLeft)            return pRoot;        if(pCur == pRoot->_pRight)            return pRoot;        Node* temp = NULL;        if(temp = _Parent(pRoot->_pLeft, pCur))            return temp;        return _Parent(pRoot->_pRight, pCur);    }

查找左孩子、右孩子时,可以直接找到,但是对于双亲节点,需要将树遍历一遍。
先判断要查找的节点是否存在—->
再判断根节点是否存在—–>
判断要查找的节点是不是根节点(如果是:就返回NULL,因为根节点没有双亲节点)—–>
再分别判断根节点的左子树、右子树是不是要查找的结点(如果是:就返回根节点,否则继续遍历)—–>
再分别遍历根节点的左、右子树。
11.计算二叉树的深度

publicint BinaryTreeDepth()    {        return _BinaryTreeDepth(_pRoot);    }privateint _BinaryTreeDepth(Node* pRoot)    {        int i = 0, j = 0;        if(pRoot == NULL)            return 0;        if(pRoot->_pLeft)            i = _BinaryTreeDepth(pRoot->_pLeft);        else            i = 0;        if(_BinaryTreeDepth(pRoot->_pRight))            j = _BinaryTreeDepth(pRoot->_pRight);        else            j = 0;        return i>j?i+1:j+1;    }

如果树的左、右子树存在,i+1=5。
不存在, i=0。

完整代码

#include <iostream>#include <windows.h>#include <string.h>#include <queue>#include <assert.h>using namespace std;template <class T>struct BinaryTreeNode//定义二叉树的节点{    BinaryTreeNode(const T& value)        :_value(value)        ,_pLeft(NULL)        ,_pRight(NULL)    {}    T _value;    BinaryTreeNode<T>* _pLeft;    BinaryTreeNode<T>* _pRight;};template<class T>class BinaryTree{    typedef BinaryTreeNode<T> Node;public:    BinaryTree()        :_pRoot(NULL)    {}    BinaryTree(const T arr[], size_t size, const T& invalid)    {        size_t index=0;        _CreateBinaryTree(_pRoot, arr, size, index, invalid);    }    BinaryTree(const BinaryTree<T>& bt)    {        _pRoot = _CopyBinaryTree(bt._pRoot);    }    BinaryTree<T>& operator=(const BinaryTree<T>& bt)    {        if(this != &bt)        {            _DestroyBinaryTree(_pRoot);            _pRoot = _CopyBinaryTree(bt._pRoot);        }        return *this;    }    ~BinaryTree()    {        _DestroyBinaryTree(_pRoot);    }    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;    }    void LevelOrder()    {        cout<<"LevelOrder"<<endl;        _LevelOrder(_pRoot);        cout<<endl;    }    Node* Find(const T& value)    {        return _Find(_pRoot, value);    }    Node* LeftChild()    {        return _pRoot->_pLeft;    }    Node* RightChild()    {        return _pRoot->_pRight;    }    Node* Parent(Node* pCur)    {        return _Parent(_pRoot, pCur);    }    int BinaryTreeDepth()    {        return _BinaryTreeDepth(_pRoot);    }private:    void _CreateBinaryTree(Node* &pRoot, const T arr[], size_t size, size_t& index, const T& invalid)    {        if(index<size && arr[index] != invalid)        {            //创建根节点            pRoot = new Node(arr[index]);            //创建左子树            _CreateBinaryTree(pRoot->_pLeft, arr, size, ++index, invalid);            //创建右子树            _CreateBinaryTree(pRoot->_pRight, arr, size, ++index, invalid);        }    }    Node* _CopyBinaryTree(Node* pRoot)    {        Node* pNode = NULL;        if(pRoot)        {            pNode = new Node(pRoot->_value);            pNode->_pLeft = _CopyBinaryTree(pRoot->_pLeft);            pNode->_pRight = _CopyBinaryTree(pRoot->_pRight);        }        return pNode;    }    void _DestroyBinaryTree(Node*& pRoot)    {        if(pRoot)        {            _DestroyBinaryTree(pRoot->_pLeft);            _DestroyBinaryTree(pRoot->_pRight);            delete pRoot;            pRoot = NULL;        }    }    void _PreOrder(Node* pRoot)    {        if(pRoot)        {            cout<<pRoot->_value<<" ";            _PreOrder(pRoot->_pLeft);            _PreOrder(pRoot->_pRight);        }    }    void _InOrder(Node* pRoot)    {        if(pRoot)        {            _InOrder(pRoot->_pLeft);            cout<<pRoot->_value<<" ";            _InOrder(pRoot->_pRight);        }    }    void _PostOrder(Node* pRoot)    {        if(pRoot)        {            _PostOrder(pRoot->_pLeft);            _PostOrder(pRoot->_pRight);            cout<<pRoot->_value<<" ";        }    }    void _LevelOrder(Node* pRoot)    {        if(pRoot == NULL)            return ;        queue<Node*> q;        q.push(pRoot);        while(!q.empty())        {            Node* temp = q.front();            if(temp->_pLeft)                q.push(temp->_pLeft);            if(temp->_pRight)                q.push(temp->_pRight);            cout<<temp->_value<<" ";            q.pop();        }    }    Node* _Find(Node* pRoot, const T& value)    {        if(pRoot == NULL)            return NULL;        if(pRoot->_value == value)            return pRoot;        Node* pNode = NULL;        if(pNode = _Find(pRoot->_pLeft, value))            return pNode;        return _Find(pRoot->_pRight, value);    }    Node* _Parent(Node* pRoot, Node* pCur)    {        assert(pCur != NULL || pRoot != NULL);        if(pCur == pRoot)            return NULL;        if(pCur == pRoot->_pLeft)            return pRoot;        if(pCur == pRoot->_pRight)            return pRoot;        Node* temp = NULL;        if(temp = _Parent(pRoot->_pLeft, pCur))            return temp;        return _Parent(pRoot->_pRight, pCur);    }    int _BinaryTreeDepth(Node* pRoot)    {        int i = 0, j = 0;        if(pRoot == NULL)            return 0;        if(pRoot->_pLeft)            i = _BinaryTreeDepth(pRoot->_pLeft);        else            i = 0;        if(_BinaryTreeDepth(pRoot->_pRight))            j = _BinaryTreeDepth(pRoot->_pRight);        else            j = 0;        return i>j?i+1:j+1;    }private:    Node* _pRoot;//根节点};int main(){    char* arr = "124###35##6";    BinaryTree<char> bt1(arr, strlen(arr), '#');    //cout<<"depth = "<<bt1.BinaryTreeDepth()<<endl;    //cout<<bt1.Parent(bt1.Find('4'))->_value;    //bt1.PreOrder();    //bt1.InOrder();    //bt1.PostOrder();    //bt1.LevelOrder();    //bt1.Find('2');    //cout<<bt1.LeftChild()->_value<<endl;    //cout<<bt1.RightChild()->_value<<endl;    //BinaryTree<char> bt2(bt1);    //BinaryTree<char> bt3;    //bt3=bt1;    system("pause");    return 0;}
0 0
原创粉丝点击