【数据结构】二叉树!!!

本文介绍了二叉树的概念,包括其定义、特点和分类,如满二叉树与完全二叉树。同时,阐述了二叉树的性质,如层数与节点数的关系,以及度数与叶节点数的关系。重点讨论了二叉树的四种遍历方法:前序、中序、后序和层序遍历,并给出了相应的遍历结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 概念:

    一颗二叉树是结点的一个有限集合,该集合为空或者是由一个根节点和一个左子树和一个右子树构成的组合。

  • 特点:

    每个结点最多有两个子树,每个子树的顺序不能变,份左子树和右子树。

  • 分类:

    满二叉树:在一棵树里面每个分支结点都存在左子树和右子树,并且所有的叶子节点都在同一层。
    完全二叉树:一棵具有N个结点的二叉树的结构和满二叉树的前N个结点相

这里写图片描述
二叉树的性质

若二叉树根结点的层数为1,那么这个非空二叉树的第i层最多有2^(i-1)个结点。
若根节点二叉树的深度为1,那么深度为K的二叉树的最大结点数是2^K-1;
对于任何一棵二叉树,如果叶节点个数为N0,度为2的非叶节点的个数为N1,那么N0 = N1+1;

二叉树的基本操作:
二叉树的遍历
这里写图片描述
前序:

  • 先访问根节点—–>左子树 —–>右子树
    结果:A B D E C F

中序:

  • 左子树—–>访问根结点—– >右子树

结果:D B E A F C

后序:

  • 左子树—–>根节点—–>访问右子树

结果:D E B F C A

层序:

  • 每一层顺序遍历二叉树

结果:A B C D E F

【二叉树的基本操作代码】

#include<stack>
#include<iostream>
using namespace std;

template<class T>
struct TreeNode
{
    TreeNode()
        :leftTree(NULL)
        ,rightTree(NULL)
    {}
    TreeNode(T& d)
        :leftTree(NULL)
         ,rightTree(NULL)
         ,data(d)
    {}
    TreeNode(const TreeNode& t)
        :leftTree(t.leftTree)
         ,rightTree(t.rightTree)
         ,data(t.data)
    {}
    TreeNode<T>* leftTree;
    TreeNode<T>* rightTree;
    T data;
};
template<class T>
class BinaryTree
{
    typedef TreeNode<T> Node;
    public:
        BinaryTree(T* arr,size_t N,T& invalid)  //construct function
            :_root(NULL)
        {
         if(arr)
         {
             size_t index = 0;
            _root = GreatTreeNode(_root,arr,N,index,invalid);       
         }
        }
        BinaryTree(BinaryTree<T>& t)        //copy construction
        {
            _root = _CopyTree(t._root);   
        }
        Node* _CopyTree(Node *root2)        //copy tree
        {
            if(NULL == root2)
                return NULL;
            Node* root1 = new Node(root2->data);
            root1->leftTree = _CopyTree(root2->leftTree);
           root1->rightTree = _CopyTree(root2->rightTree);
            return root1;
        }
        void PrePrint()                     //print by front
        {
            _PrePrint(_root);   
        }
        void _PrePrint(Node* root)
        {
            if(NULL == root)
                return ;
            cout<<root->data<<" ";
            _PrePrint(root->leftTree);
            _PrePrint(root->rightTree);
            //cout<<endl;
        }

        void PreOrder()
        {
            if(NULL == _root)
                return ;
            stack<Node*> s;
            s.push(_root);
            Node* tmp = _root;
            while(!s.empty())
            {
                tmp = s.top();
                s.pop();
                while(tmp)
                {
                    cout<<tmp->data<<" ";
                    if(tmp->rightTree)
                        s.push(tmp->rightTree);
                    tmp = tmp->leftTree;
                }
            }
        }

        void Inorder()
        {
            if(NULL == _root)
                return ;
            stack<Node*> s;
            Node *tmp = _root;
            while(!s.empty())
            {
                while(tmp)
                {
                    s.push(tmp);
                    tmp = tmp->leftTree;
                }
                tmp = s.top();
                cout<<tmp->data<<" ";
                s.pop();
                tmp = tmp->rightTree;
            }
        }
        void BackOrder()
        {
            if(NULL == _root)
                return ;
            stack<Node*> s;
            Node* tmp = _root;
            Node* flag = NULL;
            s.push(_root);
            while(!s.empty()||tmp)
            {
                while(tmp)
                {
                    if(tmp->leftTree)
                        s.push(tmp->leftTree);
                    tmp = tmp->leftTree;
                }
                tmp = s.top();
                if(NULL == tmp->rightTree || flag == tmp->rightTree)    
                {
                    cout<<tmp->data<<" ";
                    s.pop();
                    flag = tmp;
                    tmp = NULL;
                }
                else
                    tmp = tmp->rightTree;
            }
        }
/*
        void PreOrder_NoR()    //非递归前序遍历
        {
            if(NULL == _root)
                return ;
            stack<Node*> s;
            s.push(_root);
            while(!s.empty())
            {
                Node* tmp = s.top();
                s.pop();
                while(tmp)
                {
                    cout<<tmp->data<<" ";
                    if(tmp->rightTree)
                        s.push(tmp->rightTree);
                    tmp = tmp->leftTree;
                }
            }
        }

        void InOrder()     //非递归中序遍历
        {
            if(NULL == _root)
                return ;
            stack<Node*> s;
            Node*tmp = _root;
            while(!s.empty()||tmp)
            {
                while(tmp)
                {
                    s.push(tmp);
                    tmp = tmp->leftTree;
                }
                tmp = s.top();
                s.pop();
                cout<<tmp->data<<" ";
                tmp = tmp->rightTree;
            }
        }
        void BackOrder()          //非递归后序遍历
        {
            if(NULL == _root)
                return ;
            stack<Node*> s;
            Node* tmp = _root;
            Node* flag = NULL;
            while(!s.empty()||tmp)
            {
                while(tmp)
                {
                    s.push(tmp);
                    tmp = tmp->leftTree;
                }
                tmp = s.top();
                if(NULL == tmp->rightTree || flag == tmp->rightTree)
                {
                    cout<<tmp->data<<" ";
                    flag = tmp;
                    s.pop();
                    tmp = NULL;
                }
                else
                    tmp = tmp->rightTree;
            }
        }
*/
        void MidPrint()                     //Print by mid
        {
            _MidPrint(_root);
        }
        void _MidPrint(Node *root)
        {
            if(NULL == root)
                return ;
            _MidPrint(root->leftTree);
            cout<<root->data<<" ";
            _MidPrint(root->rightTree);
        }
        void BackPrint()                    //Print by back
        {
            _BackPrint(_root);
        }
        void _BackPrint(Node * root)
        {
            if(NULL == root)
                return ;
            _BackPrint(root->leftTree);
            _BackPrint(root->rightTree);
            cout<<root->data<<" ";
        }
        void FloorPrint()                       //
        {
            if(_root == NULL)
                return ;
            stack<Node*> s;
            s.push(_root);
            while(!s.empty())
            {
                Node* front = s.top();
                s.pop();
                cout<<front->data<<" ";
                if(front->leftTree)
                     s.push(front->leftTree);
                if(front->rightTree)
                    s.push(front->rightTree);
           }
        }
        size_t DepthOfTree()                    //Get tree depth
        {
            return _DepthOfTree(_root);
        }
        size_t _DepthOfTree(Node* root)
        {
            if(NULL == root)
                return 0;
            size_t leftdepth = _DepthOfTree(root->leftTree);
            size_t rightdepth = _DepthOfTree(root->rightTree);
            return leftdepth > rightdepth ? (leftdepth+1):(rightdepth + 1);
        }
        size_t leafOfKfloorTree(size_t k)           //Find K floor Node
        {
            size_t leafnum = 0;
            return  _leafOfKfloorTree(_root,k,leafnum);
        }
        size_t _leafOfKfloorTree(Node *root,size_t& k,size_t leafnum)
        {
            if(NULL == root)
                return 0;
            static size_t num = 0;
            if(leafnum == k)
            {
                ++num;
                return num;
            }
            _leafOfKfloorTree(root->leftTree,k,leafnum+1);
            _leafOfKfloorTree(root->rightTree,k,leafnum+1);
            return num;
        }
        size_t GetLeafNum()
        {
            return _GetLeafNum(_root);
        }
        size_t _GetLeafNum(Node* root)
        {
            if(NULL == root)
                return 0;
            if(NULL == root->leftTree&&NULL == root->rightTree)
                return 1;
            size_t leftNum = _GetLeafNum(root->leftTree);
            size_t rightNum = _GetLeafNum(root->rightTree);
            return leftNum + rightNum;
        }
        size_t leafNum()                        //Get Tree leaf count
        {
            return _leafNum(_root);
        }
        size_t _leafNum(Node *root)
        {
            if(NULL == root)
                return 0;
            return _leafNum(root->leftTree) + _leafNum(root->rightTree) + 1;
        }
        Node* Find(T& d)                        //Find  object data
        {
            return _Find(_root,d);
        }
        Node * _Find(Node *root,T& d)
        {
            if(NULL == root)
                return NULL;
            if(root->data == d)
                return root;
            Node* tmp = _Find(root->leftTree,d);
            if(tmp)
                return tmp;
            return _Find(root->rightTree,d);
        }

        Node* leftchild(Node* pos)                  //Get left child Node
        {
           return _leftchild(_root,pos);
        }
        Node* _leftchild(Node* root,Node* pos)
        {
            if(NULL == root||pos == NULL)
                return NULL;
            return pos->leftchild;
        }
        Node* rightchild(Node* pos)                 //Get right child node
        {
            return _rightchild(_root,pos);
        }
        Node* _rightchild(Node* root,Node* pos)
        {
            if(NULL == root||NULL == pos)
                return NULL;
            return pos->rightTree;
        }
        Node* ParentNode(Node* pos)                  //Get parent Node
        {
            return _ParentNode(_root,pos);
        }
        Node* _ParentNode(Node* root,Node* pos)
        {
            if(NULL == root||NULL == pos)
                return NULL;
            if(root->leftTree == pos||root->rightTree == pos)
                return root;
            Node* tmp = _ParentNode(root->leftTree,pos);
            if(tmp)
                return tmp;
            return _ParentNode(root->rightTree,pos);
        }
        size_t Size()                                  //Get Tree node count
        {
            return _Size(_root);
        }
        size_t _Size(Node* root)
        {
            if(NULL == root)
                return 0;
            return _Size(root->leftTree) + _Size(root->rightTree) + 1;
        }
        BinaryTree& operator=(const BinaryTree& b)
        {
            if(this != &b)
            {
                DestoryTree(_root);
                _root = _CopyTree(b._root);
            }
            return *this;
        }
        ~BinaryTree()
        {
            DestoryTree(_root);
        }
    private:
        void DestoryTree(Node *del)
        {
            if(NULL == del)
                return ;
            DestoryTree(del->leftTree);
            DestoryTree(del->rightTree);
            delete del;
            del = NULL;
        }
        Node* GreatTreeNode(Node* root,T* arr,size_t N,size_t& index,T& invalid)
        {
            root = NULL;
            if(index < N && arr[index] != invalid)
            {
                root = new Node(arr[index]);
                root->leftTree = GreatTreeNode(root,arr,N,++index,invalid);
                root->rightTree = GreatTreeNode(root,arr,N,++index,invalid);
            }
            return root;
        }


        Node *_root;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值