• 二叉树详解


       树是一种比较重要的数据结构,尤其是二叉树。二叉树是一种特殊的树,在二叉树中每个节点最多有两个子节点,一般称为左子节点和右子节点(或左孩子和右孩子),并且二叉树的子树有左右之分,其次序不能任意颠倒。本篇博客将详细为大家解析二叉树。

    首先介绍两个概念:

    满二叉树:在一棵二叉树中,如果所有分支结点都有左孩子和右孩子结点,并且叶子结点都集中在二叉树的最下层,这样的树叫做满二叉树

    如:



     

    完全二叉树:若二叉树中最多只有最下面两层的结点的度数可以小于2,并且最下面一层的叶子结点都是依次排列在该层最左边的位置上,则称为完全二叉树

    如:



     区别:满二叉树是完全二叉树的特例,因为满二叉树已经满了,而完全并不代表满。所以形态你也应该想象出来了吧,满指的是出了叶子节点外每个节点都有两个孩子,而完全的含义则是最后一层没有满,并没有满。

          

    二叉树的链式存储结构是一类重要的数据结构,定义结果为:

    Cpp代码  收藏代码
    1. //定义树的结构  
    2. struct node  
    3. {  
    4.     node * lchild;  
    5.     node * rchild;  
    6.     string data;  
    7.     //初始化  
    8.     node()  
    9.     {  
    10.         lchild=rchild=NULL;  
    11.     }  
    12. };  

    二叉树的建立

    首先我们用户输入生成一棵二叉树,要生的的二叉树如下图所示:

    #代表空结点。

     下面我们根据上面图中所示的二叉树,利用先序依次输入ABDG###E#H##C#F##(即先序遍历)

    生成二叉树的代码如下:

    Cpp代码  收藏代码
    1. //二叉树生成--先序遍历输入要生成的二叉树数据,#代表空结点  
    2. void CreateTree(node * & root)  
    3. {  
    4.      char data;  
    5.      cin>>data;  
    6.      if(data!='#')  
    7.      {  
    8.          root=new node;  
    9.          root->data=data;  
    10.            
    11.          CreateTree(root->lchild);  
    12.           
    13.          CreateTree(root->rchild);  
    14.           
    15.      }  
    16. }  

    二叉树节点查找

    采用递归的方法在二叉树root里查找只为aim的结点,若找到此节点则返回其指针,否则返回NULL

    查找代码如下:

    Cpp代码  收藏代码
    1. //检查二叉树是否包含数据aim,有则返回其指针  
    2. node * Findnode(node * & root,string aim)  
    3. {  
    4.     node * p;  
    5.     if(root==NULL)//空树  
    6.         return NULL;  
    7.     else if(root->data==aim)  
    8.         return root;  
    9.     else  
    10.     {     
    11.         p=Findnode(root->lchild,aim);  
    12.         if(p!=NULL)  
    13.             return p;  
    14.         else  
    15.             return Findnode(root->rchild,aim);     
    16.     }  
    17. }  

     这里解释一下递归中的return的意思:

    return 对当前函数来说是结束了,对调用它的父函数来说你这个函数执行完成了,父函数就会接着执行下一语句。
    没想到父函数马上又遇到一个return,父函数结束了,对爷爷函数来说父函数执行完成了,爷爷函数就接着执行下一个语句

    二叉树遍历

    1.先序遍历

    先序遍历过程是:

    1)访问根结点

    2)先序遍历左子树

    3)先序遍历右子树

    先序遍历代码为:

    Cpp代码  收藏代码
    1. void  PreOrder(node * root)//先序遍历  
    2. {  
    3.     if(root!=NULL)  
    4.     {  
    5.         cout<<root->data;  
    6.         PreOrder(root->lchild);  
    7.         PreOrder(root->rchild);  
    8.     }  
    9. }  

    2.中序遍历

    中序遍历过程是:1)中序遍历左子树

    2)访问根结点

    3)中序遍历右子树

    中序遍历的代码:

    Cpp代码  收藏代码
    1. void  InOrder(node * root)//中序遍历  
    2. {  
    3.     if(root!=NULL)  
    4.     {  
    5.           
    6.         InOrder(root->lchild);  
    7.         cout<<root->data;  
    8.         InOrder(root->rchild);  
    9.     }  
    10. }  

    3.后续遍历后序遍历过程是:

    1)后序遍历左子树

    2)后序遍历右子树3)访问根结点

    后序遍历代码为:

    Cpp代码  收藏代码
    1. void  PostOrder(node * root)//后序遍历  
    2. {  
    3.     if(root!=NULL)  
    4.     {  
    5.           
    6.         PostOrder(root->lchild);  
    7.         PostOrder(root->rchild);  
    8.         cout<<root->data;  
    9.     }  
    10. }  

    二叉树高度计算

    递归解法:
    (1)如果二叉树为空,二叉树的深度为0
    (2)如果二叉树不为空,二叉树的深度 = max(左子树深度, 右子树深度) + 1

    代码如下:

    Cpp代码  收藏代码
    1. int NodeHeight(node * root)//计算二叉树高度  
    2. {  
    3.     int lchild,rchlid;  
    4.     if(root==NULL)  
    5.         return 0;  
    6.     else  
    7.     {  
    8.         lchild=NodeHeight(root->lchild);  
    9.         rchlid=NodeHeight(root->rchild);  
    10.         return (lchild>rchlid)?(lchild+1):(rchlid+1);  
    11.     }  
    12. }  

    输出二叉树叶子节点

    递归解法:
    参考代码如下:

    Cpp代码  收藏代码
    1. void Showleaf(node * root)  
    2. {  
    3.     if(root!=NULL)  
    4.     {  
    5.         if(root->lchild==NULL&&root->rchild==NULL)  
    6.             cout<<root->data;  
    7.         Showleaf(root->lchild);//输出左子树叶子节点  
    8.         Showleaf(root->rchild);//输出右子树叶子节点  
    9.     }  
    10. }  

    运行结果为:



     

    附上源代码地址:https://github.com/longpo/algorithm/tree/master/Btree

    递归分析

    上面源代码中,大量运用了递归算法,

    下面我们来分析其中一个递归的过程。

    二叉树结构为:



     利用先序遍历,即代码为:

    Cpp代码  收藏代码
    1. void  PreOrder(node * root)//先序遍历  
    2. {  
    3.     if(root!=NULL)  
    4.     {  
    5.         cout<<root->data;  
    6.         PreOrder(root->lchild);  
    7.         PreOrder(root->rchild);  
    8.     }  
    9. }  

    画出其运行状态图:


  • 相关阅读:
    OpenSSL生成证书、密钥
    js中对String去空格
    正则表达式
    webapi调用
    记一次完整的CI持续集成配置过程(.net core+Jenkins+Gitea)
    处理asp.net core连接mysql的一个异常Sequence contains more than one matching element
    asp.net core 3.1+mysql8.0+Hangfire遇到的异常解决记
    升级到asp.net core 3.1遇到的json异常
    了解ASP.NET Core端点路由
    asp.net core 2.2升到3.1遇到的问题小记
  • 原文地址:https://www.cnblogs.com/zhuyeshen/p/11276825.html
Copyright © 2020-2023  润新知