树与二叉树

#定义及概念

一棵树是一些节点的集合。这个集合可以是空集;若不是,则一棵树由称为根(root)的节点R和若干非空的子树组成。每一个子树的根叫做根r的儿子,根r称为这些子树的根的父亲。

从定义中发现:一棵树是N个节点和N-1条边的集合。

没有儿子的节点称为树叶

具有相同父亲的节点称为兄弟

从节点n1到节点nk的路径定义为节点n1,n2...nk的一个序列。

这个路径的长称为该路径上边的条数,即为k。

从每个节点都有一条到自己长度为0的路径

树中,从根到每个节点都恰好存在一条路径

对任意节点ni,其深度为根到ni的唯一路径的长。

为ni到一片叶子最长路径的长。

如果存在从n1到n2的一条路径,那么n1是n2的一位祖先,而若n1!=n2,那么n1是n2的一个真祖先

#实现

typedef struct TreeNode *PtrToNode;

struct TreeNode
{
    ElementType Element;
    PtrToNode FirstChild;
    PtrToNode NextSibling;
};

每个树节点包括了两个指针:一个指向它的第一个儿子,另一个指向它的下一个兄弟。


之所以不使每个节点包括它全部的子节点是因为每个节点的儿子数可能变化很大而事先并不知道,这回产生大量的空间浪费。

#二叉树

二叉树是一种每个节点都不能由多于两个的儿子的树。

#实现

因为儿子的个数已经被确定,所以可以用列出所有子节点的方式实现二叉树

typedef struct TreeNode *PtrToNode;
typedef struct PtrToNode Tree;

struct TreeNode
{
    ElementType Element;
    Tree Left;
    Tree Right;
};


#应用:表达式树

表达式树是一种二叉树:他的树叶是操作数,其他节点为操作符。

因为如果不考虑一目减运算符的话,所有操作符都是二元的,所以一个表达式可以写成一颗表达式树。


而如果要把一棵表达式树展开成表达式,一般有以下几种策略:

一、通过递归产生一个带括号的左表达式,然后打印在根处的运算符,最后递归地打印一个带括号的右表达式,从而得到一个中缀表达式。这种方式(左,节点,右)称为中序遍历。

这种方式的输出为:(a+(b*c))+((d*e+f)*g)

二、递归打印出左子树,右子树,然后是节点的运算符,这种方式称为后序遍历。

它的输出为后缀表达式:abc*+de*f+g*+

三、先打印出运算符,再递归地打印左右子树,称为先序遍历。

它的输出为前缀表达式: ++a*bc*+*defg

#构造一棵表达式树

以后缀表达式为例:

整体思路是,如果读入为操作数,则新建一棵树,压入栈中,如果是运算符,则弹出前两棵树,与运算符组成一棵新树,压入栈中。

实现略。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值