简单的二叉树

树的概念

树是n(n>=0)个有限个数据的元素集合,形状像一颗倒过来的树。
这里写图片描述

结点:结点包含数据和指向其它结点的指针。
根节点:树第一个结点称为根节点。
结点的度:结点拥有的子节点个数。
叶节点:没有子节点的节点(度为0)。
父子节点:一个节点father指向另一个节点child,则child为孩子节点,father为父亲结点。
兄弟节点:具有相同父节点的节点互为兄弟节点。
节点的祖先:从根节点开始到该节点所经的所有节点都可以称为该节点的祖先。
子孙:以某节点为根的子树中任一节点都称为该节点的子孙。
树的高度:树中距离根节点最远结点的路径长度。

树的存储结构

template <class T>
struct BinaryTreeNode
{
    T _data;//用来存数据
    BinaryTreeNode* _left;//指向左孩子
    BinaryTreeNode* _right;//指向右孩子
    BinaryTreeNode(const T& x)
        :_data(x)
        , _left(NULL)
        , _right(NULL)
    {}
};

树的应用

树有很多应用,有一种树叫做哈夫曼树,它可以用来压缩存储。平时所保存的文本文件,可以用哈夫曼树进行压缩。

另外一个如图:
这里写图片描述

二叉树的结构

当处理数据过程中,二叉树的形态和大小不发生剧烈动态变化时,可以采用数组方式表示二叉树抽象数据类型。
用数组方式存储二叉树,就是用连续存储单元存储二叉树数据单元。
二叉树数组表示:
这里写图片描述
但是当,在一棵树进行删除插入等操作时,可能需要医用很多节点,为了克服这些缺点,用链表来设计出节点。
这里写图片描述

二叉树

二叉树–> 二叉树是一棵特殊的树,二叉树每个节点最多有两个孩子结点,分别称为左孩子和右孩子。
满二叉树–> 高度为N的满二叉树有2^N - 1个节点的二叉树。
完全二叉树–> 若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树

实现简单二叉树:

#pragma once
#include<iostream>
using namespace std;
#include<queue>
template <class T>
struct BinaryTreeNode
{
    T _data;
    BinaryTreeNode* _left;
    BinaryTreeNode* _right;
    BinaryTreeNode(const T& x)
        :_data(x)
        , _left(NULL)
        , _right(NULL)
    {}
};

template <class T>
class BinaryTree
{
public:
    BinaryTree()
        :_root(NULL)
    {}

    BinaryTree(T* a, size_t size)
    {
        size_t index = 0;
        _root = _CreateTree(a, size, index);
    }

    ~BinaryTree()
    {
        _Destroy(_root);
        _root = NULL;
    }

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

    }

    BinaryTree<T>& operator=(BinaryTree<T> b)
    {
        swap(_root, b._root);
        return *this;
    }

    void PrevOrder()
    {
        _PrevOrder(_root);
        cout<<endl;
    }

    void InOrder()
    {
        _InOrder(_root);
        cout << endl;
    }

    void PostOrder()
    {
        _PostOrder(_root);
        cout << endl;
    }

    void LevelOrder()
    {
        if (_root != NULL)
        {
            queue<BinaryTreeNode<int>*> q1;
            q1.push(_root);
            while (!q1.empty())
            {
                BinaryTreeNode<int>* front =q1.front();
                cout << front->_data<<" ";
                q1.pop();//其实是front,但是保存起来了。

                if (front->_left)
                {
                    q1.push(front->_left);
                }
                if (front->_right)
                {
                    q1.push(front->_right);
                }
            }
            cout << endl;
        }
    }

    int Size()
    {
        int size = 0;
        _Size(_root, size);
        return size;
    }

    int Depth()
    {
        int depth = 0;
        depth = _Depth(_root);
        return depth;
    }
protected:
    BinaryTreeNode<T>* _CreateTree(T* a, size_t size, size_t& index)
    {
        BinaryTreeNode<T>* root = NULL;
        if (index < size && (a[index] != '#'))
        {
            root = new BinaryTreeNode<T>(a[index]);
            root->_left = _CreateTree(a,size,++index);
            root->_right = _CreateTree(a, size, ++index);
        }
        return root;
    }

    void _Destroy(BinaryTreeNode<T>* &root)
    {
        if (root == NULL)
            return;
        if (root->_left == NULL && root->_right == NULL)
        {
            delete root;
            root = NULL;
            return;
        }
        _Destroy(root->_left);
        _Destroy(root->_right);
        delete root;
    }

    BinaryTreeNode<T>* _Copy(BinaryTreeNode<T>* root)
    {
        if (root == NULL)
            return NULL;
        BinaryTreeNode<T>* newRoot = new BinaryTreeNode<T>(root->_data);
        newRoot->_left = _Copy(root->_left);
        newRoot->_right = _Copy(root->_right);

        return newRoot;

    }

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

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

    void _PostOrder(BinaryTreeNode<T>* root)
    {
        if (root != NULL)
        {
            _PostOrder(root->_left);
            _PostOrder(root->_right);
            cout << root->_data<<" ";
        }
    }

    void _Size(BinaryTreeNode<T>* root, int& size)
    {
        if (root == NULL)
            return;
        else
            ++size;

        _Size(root->_left,size);
        _Size(root->_right,size);
    }

    int _Depth(BinaryTreeNode<T>* root)
    {
        int leftdepth = _Depth(root->_left);
        int rightdepth = _Depth(root->_right);
        return leftdepth > rightdepth ? leftdepth + 1 : rightdepth + 1;
    }
private:
    BinaryTreeNode<T>* _root;
};

void Test()
{
    int a[10] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 };
    BinaryTree<int> b1(a, sizeof(a) / sizeof(a[0]));
    BinaryTree<int> b2(b1);

    /*int b[10] = { 1, 6, 3, '#', '#', 4, '#', '#', 5, 2};
    BinaryTree<int> b3(b, sizeof(b) / sizeof(b[0]));

    b3 = b2;*/

    b2.PrevOrder();
    b2.InOrder();
    b2.PostOrder();

    b2.LevelOrder();

    int size = b2.Size();
    cout << "size = " << size << endl;
    int depth = b2.Depth();
    cout << "depth = " << depth << endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值