二叉树

定义

二叉树在图论中是这样定义的:二叉树是一个连通的无环图,并且每一个顶点的度不大于3.有根二叉树还要满足根节点的度不大于2.有了根节点之后,每个顶点定义了唯一的父节点,和做多2个子节点.然而,没有足够的信息来区分做节点和右节点.如果不考虑连通性,允许途中有多个连通分量,这种结构叫做森林.

分类

  1. 完全二叉树——若设二叉树的高度为h,除第h层外,其他各层的节点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树
  2. 满二叉树——–除了叶子结点外每一个节点都有左右子节点,且叶子节点都处在最底层的二叉树
  3. 平衡二叉树——-平衡二叉树又被称为AVL树,它是一颗二叉排序树,且具有以下性质:(1)它是一颗空树或它的左右两个字数的高度差绝对值不超过1,(2)左右两个字数都是一颗平衡二叉树.

相关名词

树的节点:包含一个数据元素及若干指向子树的分支;
孩子节点:节点的子树的跟
双亲节点:A节点是B的孩子,则B是A的双亲
兄弟节点:同一双亲的孩子节点;
堂兄节点:同一层上的节点;
祖先节点:从根到该节点的所经分支上的所有节点;
子孙节点:一某节点为根的子树中任一节点都称为该节点的子孙;
节点层:根节点的层恒为1,根的孩子为第二层节点,以此类推;
树的深度:书中最大的节点层;
节点的度:节点子树的个数;
树的度:书中最大的节点数;
叶子结点:度为0的节点;
分枝节点:度不为0 的节点;
有序树:子树有序的树,如:家族树;
无序树:不考虑子树的顺序的树.

主要代码实现(前中后序遍历(递归,非递归),线索化,二叉搜索树转换成一个有序的双向链表)

#pragma once
#include<iostream>  
#include<queue>  
#include<stack>
using namespace std;  

template<class T>  
struct BinaryTreeNode  
{  
    BinaryTreeNode(const T& data)  
        :_data(data)  
        ,_left(NULL)  
        ,_right(NULL)  
    {}  
    BinaryTreeNode<T>* _left;  
    BinaryTreeNode<T>* _right;  
    T _data;  
};  
template<class T>  
class BinaryTree  
{  
    typedef BinaryTreeNode<T> Node;  
public:  
    BinaryTree();  
    BinaryTree(const T* a,size_t size,const T& invalid)  
        :_root(NULL)  
    {  
        size_t index=0;  
        _root=_GreateTree(a,size,index,invalid);  
    }
    Node* _GreateTree(const T *a, size_t size, size_t& index, const T& invalid)
    {
        Node* root = NULL;
        if (a[index] != invalid&&index<size)
        {
            root = new Node(a[index]);
            root->_left = _GreateTree(a, size, ++index, invalid);
            root->_right = _GreateTree(a, size, ++index, invalid);
        }
        return root;
    }
    BinaryTree(const BinaryTree<T>& t)  
    {  
        _root=_Copy(t._root) ;  
    }  
    void PrevOrder()   //前序  
    {  
        _PrevOrder(_root);  
        cout<<endl;  
    }  
    void PrevOrderNonR()  //非递归    栈  
    {  
        stack<Node*> s;  
        Node* cur=_root;  
        while(cur||!s.empty ())  
        {  
            while(cur)      //把左子树访问完  
            {  
                cout<<cur->_data <<" ";  
                s.push (cur);  
                cur=cur->_left ;  
            }  

            Node* top=s.top ();  
            s.pop ();  
            cur=top->_right ;   
        }  
        cout<<endl;  
    }   
    void InOrder()   //中序  
    {  
        _InOrder(_root);  
        cout<<endl;  
    }  
    void InOrderNonR()  
    {  
        stack<Node*> s;  
        Node* cur=_root;  
        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 PostOrder()          //后序  
    {  
        _PostOrder(_root);  
        cout<<endl;  
    }  
    void PostOrderNonR()  
    {  
        stack<Node*> s;  
        Node* cur=_root;  
        Node* prev=NULL;  

        while(cur||!s.empty())  
        {  
            while(cur)  
            {  
                s.push (cur);  
                cur=cur->_left ;  
            }  
            Node* top=s.top ();  
            if((top->_right ==NULL)||(top->_right ==prev))  
            {  
                cout<<top->_data <<" ";  
                prev=top;  
                s.pop ();  
            }  
            else  
            {  
                cur=top->_right ;  
            }     
        }  
        cout<<endl;  
    }  
    //找第K层节点的个数  
    size_t FindKLeve(size_t k)  
    {  
        return _FindKLeve(_root,k);  
    }  
    //叶子节点个数  
    size_t LeafNum()  
    {  
        return _LeafNum(_root);  
    }  
    ~BinaryTree()  
    {  
        _Destory(_root);  
    }  
    size_t Size()  
    {  
        return _Size(_root);  
    }  
    size_t Depth()  
    {  
        return _Depth(_root);  
    }  
    Node* Find(const T& x)  
    {  
        return _Find(_root,x);  
    }  
    void LeveOder()    //层次遍历      队列  
    {  
        queue<Node*> q;  
        if(_root)  
            q.push (_root);  

        while(!q.empty ())  
        {  
            Node* front=q.front ();  
            cout<<front->_data <<" ";  
            q.pop ();  
            if(front->_left )  
                q.push (front->_left );  
            if(front->_right )  
                q.push (front->_right );  
        }  
        cout<<endl;  
    }  
protected:  
    size_t _LeafNum(Node* root)  
    {  
         static size_t count=0;  
         if(root==NULL)  
             return count;  
         if((root->_left ==NULL)&&(root->_right ==NULL))  
         {  
                ++count;  
                return count;  
         }  
         _LeafNum(root->_left );  
         _LeafNum(root->_right );  
    }  
    size_t _FindKLeve(Node* root,size_t k)  
    {  
          if(root==NULL)  
              return 0;  
          if(k==1)  
              return 1;  
          return _FindKLeve(root->_left ,k-1)+_FindKLeve(root->_right ,k-1);  
    }  
    Node* _Find(Node* root,const T& x)  
    {  
        if(root==NULL)  
            return NULL;  
        if(root->_data==x )  
            return root;  

        Node* ret=_Find(root->_left,x );  
        //左子树没有找到,从右子树找  
        if(ret==NULL)  
        {  
            ret=_Find(root->_right ,x);  
        }  
        return ret;  
    }  
    size_t _Depth(Node* root)  
    {  
        if(root==NULL)  
            return 0;  
        size_t LefD=_Depth(root->_left );  
        size_t RigD=_Depth(root->_right );  
        return LefD>RigD?LefD+1:RigD+1;  
    }  
    size_t _Size(Node* root)  
    {/* 
        static size_t count=0;  
        if(root==NULL) 
        { 
            return 0; 
        } 
        ++count; 
        _Size(root->_left ); 
        _Size(root->_right ); 

        return count;*/  


        if(root==NULL)  
            return 0;  
        return _Size(root->_left )+_Size(root->_right )+1;  
    }  
    void _Destory(Node* root)  
    {  
        if(root)  
        {  
            _Destory(root->_left );  
            _Destory(root->_right );  
            delete root;  
        }  
    }  
    void _PostOrder(Node* root)     
    {  
        if(root)  
        {  
            _PostOrder(root->_left );  
            _PostOrder(root->_right );  
            cout<<root->_data <<" ";  
        }  
    }  
    void _PostOrderNonR(Node*cur)//后序遍历二叉树非递归版本
    {
        stack<Node*> s;
        Node*prev = NULL;
        while (cur || s.empty())
        {
            while (cur)
            {
                s.push(cur);
                cur = cur->_left;
            }
            Node*top = s.top();
            if (top->_right == NULL || top->_right == prev)
            {
                s.pop();
                prev = top;
            }
            else//子问题
            {
                cur = top->_right;
            }
            cout >> endl;
        }
    }
    void _InOrder(Node* root)  
    {  
        if(root)  
        {  
            _InOrder(root->_left );  
             cout<<root->_data <<" ";  
             _InOrder(root->_right );  
        }  
    }  

    void _PrevOrder(Node* root)  
    {  
        if(root)  
        {  
            cout<<root->_data <<" ";  
            _PrevOrder(root->_left );  
            _PrevOrder(root->_right );  
        }  
    }  
    //将一颗二叉搜索树变换成一个双向链表,但不创建任何新节点
    //->终须线索化二叉搜索树(ToSort)
    /*Node* ToSort()
    {
        Node* prev = NULL;
        _ToSort(_root, prev);
        Node*head = _root;
        while (head&&head->_left)
        {
            head = head->_left;
        }
        return head;
    }
    void _ToSort(Node*cur, Node*&prev)
    {
        if (cur == NULL)
        {
            return;
        }
        _ToSort(cur->_left, prev);
        if (prev == NULL)
        {
            prev->_right = cur;
        }
        _ToSort(cur->_right, prev);
        */

private:  
    Node* _root;  
};  

void TestBinaryTree()
{
    int a[10] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 };
    BinaryTree<int> t(a, 10, '#');
    t.PrevOrder();
    t.PrevOrderNonR();
    t.InOrder();
    t.InOrderNonR();
    t.PostOrder();
    t.PostOrderNonR();
    cout << t.LeafNum() << endl;
    //cout<<t.FindKLeve (3)<<endl;  
    /*cout<<t.Size ()<<endl;
    cout<<t.Depth ()<<endl;
    BinaryTreeNode<int>* ret=t.Find (5);
    cout<<ret->_data <<endl;
    ret=t.Find (7);
    cout<<ret<<endl;
    t.LeveOder ();*/
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值