树的基本概念:

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


    结点:结点包含数据和指向其它结点的指针。

    根节点:树第一个结点称为根节点。

    结点的度:结点拥有的子节点个数。

    叶节点:没有子节点的节点(度为0)。

    父子节点:一个节点father指向另一个节点child,则child为孩子节点,father为父亲结点。

    兄弟节点:具有相同父节点的节点互为兄弟节点。

    节点的祖先:从根节点开始到该节点所经的所有节点都可以称为该节点的祖先。

    子孙:以某节点为根的子树中任一节点都称为该节点的子孙。

    树的高度:树中距离根节点最远结点的路径长度


二叉树的概念:

    二叉树是一棵特殊的树,二叉树每个节点最多有两个孩子结点,分别称为左孩子和右孩子。

二叉树的存储方式:

    (1)数组存储方式  即用一组连续的存储单元存储二叉树的数据元素。

    例如:

wKiom1cYw3GCxDqdAACF3eqTWVU541.png

    (2)链式存储方式

wKiom1cYxYiSRTJyAACS0KFS2kk419.png

    这里我们主要讨论每个结点包含三个域的情况

    二叉树的结点的结构

    template<class T>

    struct BinaryTreeNode

    {

     BinaryTreeNode(const T& x)  //构造函数

     :_data(x)

     ,_left(NULL)

     ,_right(NULL)

     { }

    

     T _data;  //结点的值

     BinaryTreeNode<T>* _left;  //指向左子树的结点

     BinaryTreeNode<T>* _right; //指向右子树的结点

    };

    

    部分代码如下:

    二叉树的遍历(前序、中序、后序、层次)

    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 _PosOrder(Node* root) //后序遍历打印二叉树

    {

if(root == NULL)

    return;

_PosOrder(root->_left);

_PosOrder(root->_right);

cout<<root->_data<<" ";

    }


    void _LevelOrder(Node* root) //层次遍历

    {

queue<Node*> p;

if(root == NULL)

{

    return;

}

p.push(root);

while (!p.empty())

{

    if(p.front()->_left != NULL)

         {

p.push(p.front()->_left);

            }

    if(p.front()->_right != NULL)

    {

p.push(p.front()->_right);

    }

    cout<<p.front()->_data<<" ";

    p.pop();

}

    }

    二叉树中结点的个数

    size_t _Size(Node* root) //求结点的个数

    {

if(root == NULL)

    return 0;

return _Size(root->_left) + _Size(root->_right) + 1;

    }

    二叉树的深度

    size_t _Depth(Node* root) //树的深度

    {

if(root == NULL)

    return 0;

size_t leftdepth = _Depth(root->_left);

size_t rightdepth = _Depth(root->_right);

return leftdepth > rightdepth ? leftdepth + 1 : rightdepth + 1;

    }

    二叉树叶子节点的个数

    size_t _LeafSize(Node* root) // 叶子节点的个数

    {

if(root == NULL)

    return 0;

if(root->_left == NULL && root->_right == NULL)

    return 1;

return _LeafSize(root->_left) + _LeafSize(root->_right);

    }

    二叉树的镜像(即交换二叉树每一个结点的左右子结点)

    void _MirrorRecursively(Node* root)//二叉树的镜像

    {

//判断根节点及左右子树是否为空

if(root == NULL || (root->_left == NULL && root->_right == NULL))

    return;

Node* temp = root->_left;  //交换左右子节点

root->_left = root->_right;

root->_right = temp;

if(root->_left != NULL)

    _MirrorRecursively(root->_left);

if(root->_right != NULL)

    _MirrorRecursively(root->_right);

    }

    判断子树问题

    bool HasSubtree(Node* root2)//判断root2是否是_root的子树

    {

bool result = false;

if(_root != NULL && root2 != NULL)

{

    if(_root->_data == root2->_data)

    {

result = DoseTree1HaveTree2(_root,root2);

    }

    if(!result)

                result = HasSubtree(_root->_left,root2);

    if(!result)

result = HasSubtree(_root->_right,root2);

        }

        return result;

    }

    bool DoseTree1HaveTree2(Node* root2)//判断在tree1中是否有以tree2根节点的左右子树结构

    {

if(root2 == NULL)

    return true;

if(_root == NULL)

    return false;

if(_root->_data != root2->_data)

    return false;

return DoseTree1HaveTree2(_root->_left,root2->_left) && DoseTree1HaveTree2(_root->_right,root2->_right);

    }

    以上只是部分代码,具体源代码如下:

    

    #pragma once 

    #include<iostream>

    #include<queue>

    using namespace std;


    //二叉树中结点的结构

    template<class T>

    struct BinaryTreeNode

    {

     BinaryTreeNode(const T& x)  //构造函数

     :_data(x)

     ,_left(NULL)

     ,_right(NULL)

     { }  

     T _data;  //结点的值

     BinaryTreeNode<T>* _left;  //指向左子树的结点

     BinaryTreeNode<T>* _right; //指向右子树的结点

    };


    template<class T>

    class BinaryTree

    {

     typedef BinaryTreeNode<T> Node;//简化命名

    public:

     BinaryTree() //默认构造函数

     :_root(NULL)

     { }

    

     BinaryTree(const T* a,size_t size,const T& invalid) //构造函数

     :_root(NULL)

     {

     size_t index = 0;

     _root = _CreateTree(a,size,invalid,index); //创建一个二叉树

     }

    

     BinaryTree(const BinaryTree<T>& t) //拷贝构造函数

     :_root(NULL)

     {

     _Copy(t._root);

     }

    

     BinaryTree<T>& operator=(const BinaryTree<T>& t) //赋值函数

     {

     if(this != &t)

     {

     _Destroy(t._root);

     _Copy(t._root);

     }

     return *this;

     }

    

     ~BinaryTree() //析构函数

     {

     if(_root)

     {

     _Destroy(_root);

     }

     }

    

     void PrevOrder() //前序遍历打印二叉树

     {

     cout<<"前序遍历:";

     _PrevOrder(_root);

     cout<<endl;

     }

    

     void InOrder()//中序遍历打印二叉树

     {

     cout<<"中序遍历:";

     _InOrder(_root);

     cout<<endl;

     }

    

     void PosOrder()//后续序遍历打印二叉树

     {

     cout<<"后序遍历:";

     _PosOrder(_root);

     cout<<endl;

     }

    

     void LevelOrder() //层次遍历

     {

     cout<<"层次遍历:";

     _LevelOrder(_root);

     cout<<endl;

     }

    

     size_t Size() //求结点的个数

     {

     return _Size(_root);

     }

    

     size_t Depth()//树的深度

     {

     return _Depth(_root);

     }

    

     size_t LeafSize() //叶子节点个数 

     {

     return _LeafSize(_root);

     }

    

     bool HasSubtree(Node* root2)//判断root2是否是_root的子树

     {

     bool result = false;

     if(_root != NULL && root2 != NULL)

     {

     if(_root->_data == root2->_data)

     {

     result = DoseTree1HaveTree2(_root,root2);

     }

     if(!result)

     result = HasSubtree(_root->_left,root2);

     if(!result)

     result = HasSubtree(_root->_right,root2);

     }

     return result;

     }

    

     void MirrorRecursively()//二叉树的镜像

     {

     _MirrorRecursively(_root);

     }

    

    

    protected:

     Node* _CreateTree(const T* a,size_t size,const T& invalid,size_t& index) //创建一个二叉树

     {

     Node* root = NULL;

     if(a[index] != invalid && index < size)

     {

     root = new Node(a[index]);

     root->_left = _CreateTree(a,size,invalid,++index);

     root->_right = _CreateTree(a,size,invalid,++index);

     }

     return root;

     }

    

     void _Copy(Node* sroot)//拷贝函数

     {

     Node* root = NULL;

     if(sroot == nul) //判断根节点

     return;

     if(sroot->_left && sroot->_right) //判断根节点的左右子树

     {

     root = new Node(sroot->_data);

     return ;

     }

     root->_left = _Copy(sroot->_left);//依次拷贝左子树

     root->_right = _Copy(sroot->_right);//依次拷贝右子树

     }

    

     void _Destroy(Node* root)//销毁二叉树

     {

     if(root == NULL)

     {

     return;

     }

     if(root->_left && root->_right)

     {

     delete root;

     root = NULL;

     return;

     }

     _Destroy(root->_left);

     _Destroy(root->_right);

     }

    

     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 _PosOrder(Node* root) //后序遍历打印二叉树

     {

     if(root == NULL)

     return;

     _PosOrder(root->_left);

     _PosOrder(root->_right);

     cout<<root->_data<<" ";

     }

    

     void _LevelOrder(Node* root) //层次遍历

     {

     queue<Node*> p;

     if(root == NULL)

     {

     return;

     }

     p.push(root);

     while (!p.empty())

     {

     if(p.front()->_left != NULL)

     {

     p.push(p.front()->_left);

     }

     if(p.front()->_right != NULL)

     {

     p.push(p.front()->_right);

     }

     cout<<p.front()->_data<<" ";

     p.pop();

     }

     }

    

     void _MirrorRecursively(Node* root)//二叉树的镜像

     {

     //判断根节点及左右子树是否为空

     if(root == NULL || (root->_left == NULL && root->_right == NULL))

     return;

     Node* temp = root->_left;  //交换左右子节点

     root->_left = root->_right;

     root->_right = temp;

     if(root->_left != NULL)

     _MirrorRecursively(root->_left);

     if(root->_right != NULL)

     _MirrorRecursively(root->_right);

     }

    

     size_t _Size(Node* root) //求结点的个数

     {

     if(root == NULL)

     return 0;

     return _Size(root->_left) + _Size(root->_right) + 1;

     }

    

     size_t _Depth(Node* root) //树的深度

     {

     if(root == NULL)

     return 0;

     size_t leftdepth = _Depth(root->_left);

     size_t rightdepth = _Depth(root->_right);

     return leftdepth > rightdepth ? leftdepth + 1 : rightdepth + 1;

     }

    

     size_t _LeafSize(Node* root) // 叶子节点的个数

     {

     if(root == NULL)

     return 0;

     if(root->_left == NULL && root->_right == NULL)

     return 1;

     return _LeafSize(root->_left) + _LeafSize(root->_right);

     }

    

     bool DoseTree1HaveTree2(Node* root2)//判断在tree1中是否有以tree2根节点的左右子树结构

     {

     if(root2 == NULL)

     return true;

     if(_root == NULL)

     return false;

     if(_root->_data != root2->_data)

     return false;

     return DoseTree1HaveTree2(_root->_left,root2->_left) && DoseTree1HaveTree2(_root->_right,root2->_right);

     }

    

    protected:

     Node* _root;//根节点

    };

    

    void Test()

    {

     int a1[10] = {1,2,3,'#','#',4,'#','#',5,6};

     int a2[15] = {1,2,'#',3,'#','#',4,5,'#',6,'#',7,'#','#',8,};

     int a3[5] = {2,3,'#','#',4};

    

     BinaryTree<int> t1(a1,10,'#');

     BinaryTree<int> t2(a2,15,'#');

     BinaryTree<int> t3(a3,5,'#');

    

     cout<<"t1遍历二叉树(前序,中序,后序,层次):"<<endl;

     t1.PrevOrder();

     t1.InOrder();

     t1.PosOrder();

     t1.LevelOrder();

     cout<<"二叉树结点的个数:"<<t1.Size()<<endl;

     cout<<"二叉树的深度:"<<t1.Depth()<<endl;

     cout<<"二叉树的叶子节点数:"<<t1.LeafSize()<<endl;

     cout<<"二叉树的镜像:"<<endl;

     t1.MirrorRecursively();

     t1.PrevOrder();

     cout<<endl;

    

     cout<<"t2遍历二叉树(前序,中序,后序,层次):"<<endl;

     t2.PrevOrder();

     t2.InOrder();

     t2.PosOrder();

     t2.LevelOrder();

     cout<<"二叉树结点的个数:"<<t2.Size()<<endl;

     cout<<"二叉树的深度:"<<t2.Depth()<<endl;

     cout<<"二叉树的叶子节点数:"<<t2.LeafSize()<<endl;

     cout<<"二叉树的镜像:"<<endl;

     t2.MirrorRecursively();

     t2.PrevOrder();

     cout<<endl;

    }