C++实现二叉树的基本操作(递归+非递归)

关于二叉树的概念不再赘述,看一个简单例子:
这里写图片描述

下面看代码:


#include <iostream>
#include <assert.h>
#include <stack>
#include <queue>

using namespace std;

template <class T>
struct BinaryTreeNode   //结点定义
{
    T _data;
    BinaryTreeNode<T>* _left;
    BinaryTreeNode<T>* _right;

    BinaryTreeNode(const T& x)
        :_data(x)
        ,_left(NULL)
        ,_right(NULL)
    {}
};

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

    //构造函数
    BinaryTree(T* a, size_t n, size_t& index,const T& invalid = T())
    {
        _root = _CreateTree(a, n, index,invalid);
    }

    ~BinaryTree()
    {
        _Destory(_root);
    }

    BinaryTree(const BinaryTree<T>& t)
    {
        _root=_Copy(t._root);
    }

    //先序遍历
    void PrevOrder()
    {
        _PrevOrder(_root);
        cout << endl;
    }
    //非递归先序遍历
    void PrevOrderNonR()
    {
        Node* cur = _root;
        stack<Node*> s;
        while (cur || !s.empty())           
        {
            while (cur)                     //一直进行左子树进入,并将可以访问的结点压栈
            {
                cout << cur->_data << " ";
                s.push(cur);
                cur = cur->_left;
            }                               //出while循环时,该结点没有左子树了

            Node* top = s.top();            //top记录的是最后一个可以走的结点
            s.pop();                        //将其出栈
            cur = top->_right;              //cur指向该节点的右子树,然后回到第一个while循环当做子问题处理
        }
        cout << endl;
    }

    //中序遍历
    void InOrder()
    {
        _InOrder(_root);
        cout << endl;

    }

    //中序非递归
    void InOrderNonR()
    {
        Node* cur = _root;
        stack<Node*> s;
        while (cur || !s.empty())
        {
            while (cur)                     
            {
                s.push(cur);
                cur = cur->_left;
            }                               

            Node* top = s.top();            
            cout << top->_data << " ";      
            s.pop();                        
            cur = top->_right;              
        }
        cout << endl;
    }

    //后序
    void BackOrder()
    {
        _BackOrder(_root);
        cout << endl;
    }

    //后序非递归
    void PostOrderNonR()
    {
        Node* cur = _root;
        Node* prev = _root;
        stack<Node*> s;
        while (cur || !s.empty())
        {
            while (cur)
            {
                s.push(cur);
                cur = cur->_left;
            }

            Node* top = s.top();

            if (NULL == top->_right || prev == top->_right)
            {
                cout << top->_data << " ";
                s.pop();
                prev = top;
            }

            else
            cur = top->_right;
        }
        cout << endl;
    }

    //层序遍历
    void LevelOrder()
    {
        queue<Node*> q;
        if (_root)
            q.push(_root);
        while (!q.empty())
        {
            Node* tmp = q.front();
            cout << tmp->_data << "  ";
            q.pop();
            if (tmp->_left)
                q.push(tmp->_left);
            if (tmp->_right)
                q.push(tmp->_right);
        }
        cout << endl;
    }

    //计算节点个数
    size_t Size()
    {
        return _Size(_root);
    }

    //在树中寻找x
    Node* Find(const T& x)
    {
        queue<Node*> q;
        if (_root)
            q.push(_root);
        while (!q.empty())
        {
            Node* tmp = q.front();
            q.pop();
            if (x == tmp->_data)
                return tmp;
            if (tmp->_left)
                q.push(tmp->_left);
            if (tmp->_right)
                q.push(tmp->_right);
        }
        return NULL;
    }

    //在树中寻找x(递归法)
    Node* FindR(const T& x)
    {
        return _FindR(_root, x);
    }

    //计算叶子节点个数
    size_t GetLeafSize()
    {
        size_t count = 0;
        return _GetLeafSize(_root, count);
    }

    size_t GetLeafSize2()
    {
        return _GetLeafSize2(_root);
    }

    //求树的深度(从1开始)
    size_t Depth()
    {
        size_t leftdepth = 0;
        size_t rightdepth = 0;

        return _Depth(_root, leftdepth, rightdepth);
    }

    //计算第K层叶子节点的个数
    size_t GetKLeafSize(size_t k)
    {
        assert(k > 0);
        return _GetKLeafSize(_root,k);
    }

    //求深度(法2)
    size_t Depth2()
    {
        return _Depth2(_root);
    }

protected:
    // size_t& index
    // 传引用原因:递归栈中,index分别属于不同的栈帧,++index会加在不同的栈帧上的index,
    // 递归退层时,index的值会恢复成所退到的递归层中的index
    Node* _CreateTree(T* a, size_t n, size_t& index,const T& invalid)
    {
        Node* root = NULL;
        if (index < n && a[index] != invalid)
        {
            root = new Node(a[index]);
            root->_left = _CreateTree(a, n, ++index,invalid);
            root->_right = _CreateTree(a, n, ++index, invalid);
        }
        return root;
    }

    void _PrevOrder(Node* root)
    {
        if (root == NULL)
            return;
        cout << root->_data << "  ";
        _PrevOrder(root->_left);
        _PrevOrder(root->_right);
    }

    void _InOrder(Node* root)
    {
        if (root == NULL)
            return;
        _InOrder(root->_left);
        cout << root->_data << "  ";
        _InOrder(root->_right);
    }

    void _BackOrder(Node* root)
    {
        if (root == NULL)
            return;
        _BackOrder(root->_left);
        _BackOrder(root->_right);
        cout << root->_data << "  ";
    }

    size_t _Size(Node* root)
    {
        if (root == NULL)
            return 0 ;
        return _Size(root->_left) + _Size(root->_right) + 1;
    }

    size_t _GetLeafSize(Node* root,size_t& count)
    {
        if (root == NULL)
            return 0;
        if (root->_left == NULL&&root->_right == NULL)
            count++;
        _GetLeafSize(root->_left,count);
        _GetLeafSize(root->_right,count);
        return count;
    }



    size_t _GetKLeafSize(Node* root,size_t k) 
    {
        if (NULL==root)
        {
            return 0;
        }
        if (1 == k)
        {
            return 1;
        }
        return _GetKLeafSize(root->_left, k - 1) + _GetKLeafSize(root->_right, k - 1);
    }

    size_t _Depth(Node* root,size_t& left,size_t& right)
    {
        if (root == NULL)
            return 0;
        if (root->_left)
        {
            left++;
            _Depth(root->_left, left, right);
        }
        if (root->_right)
        {
            right++;
            _Depth(root->_right, left, right);
        }
        return left > right ? left : right;
    }

    size_t _Depth2(Node* root)
    {
        if (NULL == root)
        {
            return 0;
        }
        int left = _Depth2(root->_left);
        int right = _Depth2(root->_right);
        return left > right ? left+1 : right+1;
    }

    Node* _FindR(Node* root, const T& x) 
    {
        if (NULL == root)
            return NULL;
        if (x == root->_data)
        {
            return root;
        }
        Node* ret = _FindR(root->_left, x);
        if (ret)
            return ret;
        return _FindR(root->_right, x);
    }

    //后序析构,不用保存当前结点的指针
    void _Destory(Node* root)
    {
        if (NULL == root)
            return;
        _Destory(root->_left);
        _Destory(root->_right);
        delete root;
    }

    Node* _Copy(Node* root)
    {
        if (NULL == root)
            return NULL;
        Node* newRoot = new Node(root->_data);
        newRoot->_left = _Copy(root->_left);
        newRoot->_right = _Copy(root->_right);
        return newRoot;
    }

protected:
    Node* _root;
};

void Test()
{
    int a[] = { 1,2,3,'#','#',4,'#','#',5,6 };
    size_t index = 0;
    BinaryTree<int> t(a, sizeof(a) / sizeof(a[0]), index, '#');
    cout << "先序遍历:";
    t.PrevOrder();

    cout << "非递归先序遍历:";
    t.PrevOrderNonR();

    cout << "中序遍历:";
    t.InOrder();

    cout << "非递归中序遍历:";
    t.InOrderNonR();

    cout << "后序遍历:";
    t.BackOrder();

    cout << "非递归后序遍历:";
    t.PostOrderNonR();
    cout << "层序遍历:";
    t.LevelOrder();

    cout << "结点个数:"<< t.Size() << endl;
    BinaryTreeNode<int>* ret = NULL;
    ret = t.Find(5);
    cout <<"Find 5 : "<< ret->_data << endl;

    cout << "计算叶节点个数:"<<t.GetLeafSize() << endl;

    cout << "Depth: "<<t.Depth() << endl;

    cout << "第 3 层叶节点个数:" << t.GetKLeafSize(3) << endl;

    cout << "Depth2:" << t.Depth2() << endl;

    ret = t.FindR(5);
    cout << "FindR 5 : " << ret->_data << endl;

    BinaryTree<int> t2(t);
    cout << "t2 先序遍历:";
    t2.PrevOrder();

}

int main()
{
    Test();
    return 0;
}

运行结果:
这里写图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值