二叉树

二叉树

一:树
树是N个有限个数的集合,形状像一颗到过来的树。如下:
树
树是一种特殊的数据结构有点像链表,每个节点都包括指针域和一个数据域。
这里写图片描述
根节点:树的第一个节点;
节点的度:树拥有子节点的个数;
叶节点:没有子节点的节点;
树的高度:树中距离根节点最远的路径长度。
父子节点:一个节点father指向另外一个节点child,father这个节点就是父节点,child这个节点就是子节点。
二:二叉树
二叉树: 二叉树是一种特殊的树,在二叉树中每个节点最多有两个子节点,一般称为左子节点和右子节点(或左孩子和右孩子),并且二叉树的子树有左右之分,其次序不能任意颠倒。
构建一个树的结构,里面包括数据,左子树,右子树。二叉树是一种的典型的递归结构。递归要掌握两个条件(1:子问题,2:递归出口)。
定义一个简单的二叉树的结构:

struct BinaryTreeNode
{
    T _data;//数据
    BinaryTreeNode<T>* _left;//左子树
    BinaryTreeNode<T>* _right;//右子树

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

二叉树的简单实现:
1:二叉树的深度;
2:二叉树的节点的个数;
3:二叉树的叶子节点的个数;
4:二叉树第K层节点的个数;

template<class T>
class BinaryTree
{
    typedef BinaryTreeNode<T>  Node;
public:
    BinaryTree()
        :_root(NULL)
    {}
    BinaryTree(const BinaryTree<T> &t)
    {
        _root = _copy(t._root);
    }
    BinaryTree<T>&operator = (BinaryTree<T> &t)
    {
        swap(_root, t._root);
        return *this;
    }
    ~BinaryTree()
    {
        _Destroy(_root);
    }
    BinaryTree(const T*a, size_t n, const T&invalued = T())
    {
        size_t indes = 0;
        _root = _CreatTree(a, n,indes,invalued);//创建一个二叉树
    }
    //数节点的个数
    size_t Size()
    {
        return _Size(_root);
    }
    //深度
    size_t Depth()
    {
        return _Depth(_root);
    }
    //叶子节点的个数
    size_t LeftSize()
    {
        return _LeftSize(_root);
    }
  //第k层节点的个数
    int GetkLevel(Node *root, int k)
    {
        if (root == NULL||k<1)
        {
            return 0;
        }
        if (k == 1)
        {
            return 1;
        }
        int leftGetkLevel = GetkLevel(root->_left, k - 1);
        int rightGetkLevel = GetkLevel(root->_right, k - 1);
        return (leftGetkLevel + rightGetkLevel);
    }
protected:
    Node*_CreatTree(const T*a, size_t n, size_t &indes, const T&invalued)
     {
        assert(a);
        Node* root = NULL;

        if (indes<n && a[indes] != invalued)
        {
            root = new Node(a[indes]);//创建根节点
            root->_left = _CreatTree(a, n,++indes,invalued);
            root->_right= _CreatTree(a, n,++indes,invalued);
        }
        return root;
    }
    //拷贝
    Node *_copy(Node *node)
    {
        Node*cur = node;
        Node root = NULL;//
        if (cur)
        {
            root = new Node(cur->_data);//创建新节点
            root->_left = _copy(cur->_left);//递归调用
            root->_right = _copy(cur->_right);//递归调用
        }
        return root;
    }
    //删除
    void _Destroy(Node *node)
    {
        Node* del = node;
        if (del)
        {
            _Destroy(del->_left);
            _Destroy(del->_right);
            delete del;
            del = NULL;
        }
    }
    //树节点的个数
    size_t _Size(Node *root)
    {
        if (root == NULL)
        {
            return 0;
        }
        return _Size(root->_left) + _Size(root->_right) + 1;
    }
    //深度
    size_t _Depth(Node *root)
    {
        Node *cur = root;
        if (cur == NULL)
        {
            return 0;
        }
        //比较左子树和右子树的大小
        return 1 + (_Depth(cur->_left) > _Depth(cur->_right)
            ? _Depth(cur->_left) : _Depth(cur->_right));
    }
    //叶子节点的个数
    size_t _LeftSize(Node *root)
    {
        Node*cur = root;
        if (NULL == cur)//空树
        {
            return 0;
        }
        if (cur->_left == NULL&&cur->_right == NULL)//只有根节点
        {
            return 1;
        }
        return _LeftSize(cur->_left)+_LeftSize(cur->_right);//左子树与右子树的和
    }

protected:
    Node  *_root;
};
void TestBinaryTree()
{
    int a1[10] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 };
    size_t sz = sizeof(a1) / sizeof(a1[0]);
    BinaryTree<int> t(a1, sz, '#');
}

小结:
二叉树的是一种特殊的数据结构,可以通过递归来访问节点的数据域和子树的节点。假设每一次遍历都是从根节点开始,先遍历左子树,这时会生成函数栈帧,当左子树的下一个左子树为空,返回上一级,此时函数栈帧销毁,一直回退到根节点,然后遍历右子树,当右子树的下一个左子树为空测遍历结束。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值