NOJ-建立二叉树的二叉链表存储结构

建立二叉树的二叉链表存储结构

在这里插入图片描述

二叉树的链式存储表示

typedef struct BiTNode{
    char data;
    struct BiTNode *lchild, *rchild;//左右孩子指针
} BiTNode, *BiTree;
  • 二叉树的结点由一个数据元素和分别指向其左右子树的两个指针域组成。
  • 有时为了便于找到结点的双亲,则可以在结点结构中增加一个指向其双亲的指针域。

二叉树的建立

A(B(#,D),C(E(#,F),#))

观察输入的字符串,不难看出二叉树的建立过程如下:
1.一个字符后紧接一个括号,括号中间有一个’,’,表明括号里面的内容是该结点的子树,逗号左边是左子树,右边是右子树。
2.根节点的左右子树,又可以进行进一步的拆分,形成新的左右子树。二叉树的建立是一个递归定义。

void CreateBiTree(BiTree *p)
{
    char c, s;
    (*p) = (BiTree)malloc(sizeof(BiTNode));
    c = getchar();
    s = c;
    c = getchar();
    (*p)->lchild = NULL;
    (*p)->rchild = NULL;
    if(s==','){
        (*p)->data = c;
        s = getchar();
        if(s=='('){
            CreateBiTree(&((*p)->lchild));
            CreateBiTree(&((*p)->rchild));
        }
    }
    else{
        (*p)->data = s;
        if(c=='('){
            CreateBiTree(&((*p)->lchild));
            CreateBiTree(&((*p)->rchild));
        }
    }
}

其实这一段代码我也没有想到,是看网上一个学长的代码得到的。
其大致思路是:

  • 进入一个子树两种字符类型(以A为例)
    1. A( 遇到这种组合说明要创建A的子树。
    2. ,A( 遇到这种情况说明A是上一级树的右子树,且A也需要创建子树。
  • 不满足上述两种情况说明到了叶子结点。

分析输入

  1. 读取到A和(说明需要创建子树,递归调用自身。
  2. 读取到B和(继续递归。
  3. 读取到#和,不满足创建子树的条件说明递归结束,退栈,将#赋予上一结点的左子树,然后同样地将D赋予右子树,再次退栈。
  4. B的子树创建完毕,读取到,和C和(说明需要递归调用。
  5. 读取到E和(继续递归。
  6. 读取到#和,不满足递归条件,将#和F分别赋予左右子树后退栈。
  7. C的左子树创建完成,读取到#和)说明已经到了叶子结点,把#给C的右子树。
  8. 到此为止A的左右子树B和C都创建完毕,且B和C的子树也创建完毕。递归结束。

前序遍历二叉树

前序遍历二叉树的操作定义为
(1)访问根节点。
(2)先序遍历左子树。
(3)先序遍历右子树。
二叉树的递归遍历是考试的常考点,因为它充分体现了递归代码的简洁性。也便于在考试中出题。

void PreOrderTraverse(BiTree T)
{
    if(T)
        printf("%c", T->data);
    if(T->lchild){
        PreOrderTraverse(T->lchild);
    }
    if(T->rchild){
        PreOrderTraverse(T->rchild);
    }
}

源代码:

#include<stdio.h>
#include<stdlib.h>
typedef struct BiTNode{
    char data;
    struct BiTNode *lchild, *rchild;//左右孩子指针
} BiTNode, *BiTree;
void CreateBiTree(BiTree *T);//创建二叉树
void PreOrderTraverse(BiTree T);//前序遍历二叉树
int main()
{
    BiTree T = (BiTree)malloc(sizeof(BiTNode));
    CreateBiTree(&T);
    PreOrderTraverse(T);
}
void CreateBiTree(BiTree *p)
{
    char c, s;
    (*p) = (BiTree)malloc(sizeof(BiTNode));
    c = getchar();
    s = c;
    c = getchar();
    (*p)->lchild = NULL;
    (*p)->rchild = NULL;
    if(s==','){
        (*p)->data = c;
        s = getchar();
        if(s=='('){
            CreateBiTree(&((*p)->lchild));
            CreateBiTree(&((*p)->rchild));
        }
    }
    else{
        (*p)->data = s;
        if(c=='('){
            CreateBiTree(&((*p)->lchild));
            CreateBiTree(&((*p)->rchild));
        }
    }
}
void PreOrderTraverse(BiTree T)
{
    if(T)
        printf("%c", T->data);
    if(T->lchild){
        PreOrderTraverse(T->lchild);
    }
    if(T->rchild){
        PreOrderTraverse(T->rchild);
    }
}
  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alfred young

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值