关于二叉树的创建、遍历等问题

本文详细介绍了二叉树的创建方法,包括基于先序、中序及后序遍历序列创建二叉树的过程,并提供了相关的算法实现。此外,还讨论了如何计算二叉树的节点个数、叶子节点个数、深度等属性。

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

关于二叉树的创建、遍历等问题

树是一种非线性结构,其中以二叉树应用最为广泛,比如说优化算法的堆排就是以二叉树为基础;所以先来从二叉树的创建、遍历总结起;定义二叉树 以及节点的空间申请  用遍历结果创建二叉树 计算叶子节点个数、节点个数、各种分支个数等
  1. 定义二叉树 以及节点的空间申请
  typedef char ElemType;      
typedef struct node
{
    node * leftchild;
    node *rightchild;
    ElemType data; 
}BTtree;  

 BTtree *buynode()
{
    BTtree *s=(BTtree *)malloc(sizeof(BTtree));
    if(s==NULL)exit(0);
    return s;
}
  1. 创建二叉树 (首先以一种简单的方法创建二叉树:假设二叉树的左右孩子为NULL时用’#’来代替)
BTtree* creat_tree1()
{
    BTtree *s=NULL;
    ElemType tmp;
    scanf("%c",&tmp);
    if(tmp!='#')
    {
        s=buynode();                //节点空间的申请
        s->data=tmp;
        s->leftchild=creat_tree1();     //通过递归来创建二叉树
        s->rightchild=creat_tree1();
    }
    return s;
}

当然这种方法比较简单,接下来先总结二叉树的遍历然后再总结通过不同的遍历顺序来创建二叉树

3. 二叉树的遍历(觉得老师上课讲的二叉树例子特别有代表性)

二叉树
(1)、先序遍历(结果为:ABCDEFGH)

     void pre_order(BTtree *r)          
{
    if(r==NULL)return;
    pre_order(r->leftchild);       //三种遍历的方法都是采用递归
    printf("%c ",r->data);
    pre_order(r->rightchild);
}
(2)、中序遍历(结果为:CBEDFAGH )
   void in_order(BTtree *r)          
{
    if(r==NULL)return;
    in_order(r->leftchild);
    printf("%c ",r->data);
    in_order(r->rightchild);
}
(3)、后序遍历(结果为:CEFDBHGA)
  void las_order(BTtree *r)       
{
    if(r==NULL)return;
    las_order(r->leftchild);
    las_order(r->rightchild);
    printf("%c ",r->data);
}
  1. 已知两种不同的遍历顺序创建二叉树
    (1)已知先序和中序来创建二叉树
int find(char *is,int n,ElemType x)//find函数的目的是比较数据是否在两种遍历次序中都有出现并返回中序中的位置
{
    for(int i = 0;i<n;++i)           
    {
        if(is[i] == x)
            return i;
    }
    return -1;
}
    BTtree * cre_pi(char *ps,char *is,int n)
{
    int pos = find(is,n,ps[0]);//调用find 如果没有找到则说明先序中的数据在中序中没有找到
    if(pos == -1) exit(1);
    BTtree *s = NULL;
    if(n > 0)
    {
        s = buynode();
        s->data = ps[0];
        s->leftchild = cre_pi(ps+1,is,pos);//分为左右子树来创建时注意每次传入的位置
        s->rightchild = cre_pi(ps+pos+1,is+pos+1,n-pos-1);
    }
    return s;
}
BTtree * create_pi(char *ps,char *is)
{
    if(ps == NULL || is == NULL)
    {
        return NULL;
    }else
    {
        int n = strlen(ps);
        return cre_pi(ps,is,n);
    }
}

(2)已知中序和后序来创建二叉树

BTtree * cre_il(char *is,char *ls,int n)
{
    int pos=Find(is,n,ls[n-1]);
    if(pos==-1)exit; 
    BTtree *s=NULL;
    if(n>0)
    {
       s=buynode();
       s->data=ls[n-1];
       s->leftchild=cre_il(is,ls,pos);
       s->rightchild=cre_il(is+pos+1,ls+pos,n-pos-1);
    }
    return s;
}
BTtree * creat_il(char *is,char *ls)
{
    if(is==NULL || ls==NULL) return NULL;
    else
    {
        int n=strlen(is);
        return cre_il(is,ls,n);
    }
}

在创建二叉树时,只考虑了一种没有重复数据的二叉树创建方法,如果有重复数据,则可能创建出错误的二叉树;关于这个问题,还有待思考。。。

  1. 二叉树的某些常用函数
    (1)二叉树的节点个数
  int size(BTtree *ptr)
{
    int size=0;
    if(ptr==NULL) size=0;
    else size=1+size(ptr->leftchild)+size(ptr->rightchild);
    return size;
}
 (2)二叉树的叶子节点个数
int size_leaf(BTtree *ptr)
{
    if(ptr==NULL) return 0;
    else if(ptr->leftchild==NULL && ptr->rightchild==NULL) return 1;
    else return size_leaf(ptr->leftchild)+size_leaf(ptr->rightchild);
}
 (3)二叉树的深度
int depth(BTtree *ptr)
{
    if(ptr==NULL)return 0;
    else
    {
        return depth(ptr->leftchild)>depth(ptr->rightchild)? 
        depth(ptr->leftchild)+1 :depth(ptr->rightchild)+1;
    }
}
 (4)判断是否为满二叉树
bool full_binarytree(BTtree *ptr)    
{
    int d=depth(ptr);//树的深度
    int le=size_leaf(ptr);//叶子节点
    int n=pow(2,(d-1)*1.0);//求满二叉树的叶子节点
    if(le==n)return 1;
    else return 0;
}
 (5)求树的双分支节点个数
 int size_treebrch(BTtree *ptr)
{
    if(ptr==NULL)return 0;
    else
    {
        int size=0;
        if(ptr->leftchild!=NULL && ptr->rightchild!=NULL)size=1;
        return size+size_treebrch(ptr->leftchild)+size_treebrch(ptr->rightchild);
    }
}
 (6)求二叉树的单分支节点个数
int size_onebrch(BTtree *ptr)
{
    if(ptr==NULL)return 0;
    else
    {
        int size=0;
        if(ptr->leftchild!=NULL && ptr->rightchild==NULL || ptr->leftchild==NULL && ptr->rightchild!=NULL ) size=1;
        return size+size_onebrch(ptr->leftchild)+size_onebrch(ptr->rightchild);
    }
}
(7)求二叉树的左单分支节点个数
int size_onelbrch(BTtree *ptr)
{
    if(ptr==NULL)return 0;
    else
    {
        int size=0;
        if(ptr->leftchild!=NULL && ptr->rightchild==NULL)size=1;
        return size+size_onelbrch(ptr->leftchild)+size_onelbrch(ptr->rightchild);
    }
}
(8)求二叉树的右单分支节点个数
int size_onerbrch(BTtree *ptr)
{
    if(ptr==NULL)return 0;
    else
    {
        int size=0;
        if(ptr->leftchild==NULL && ptr->rightchild)size=1;
        return size+size_onerbrch(ptr->leftchild)+size_onerbrch(ptr->rightchild);
    }
}

在利用中序先序或者中序后序(先序后序是没有办法创建二叉树的,因为没有办法确定左右子树从哪里分)来建立二叉树时,除过递归的方法 用栈也可以实现 这个以后再总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值