二叉树的存储方式——数组&指针

二叉树的数组存储

有一说一,看到这个很多人应该是诧异的,因为就二叉树那个尿性 ,一对多的性质,如果是使用数组存储,线性表和一个二维性质的图形怎么能对应上?

这就要提到上一篇树的博客的一个性质(说过在存储会用上的)
在这里插入图片描述
因为每一个结点(除根节点)都有双亲结点,也可能有孩子结点,他们的位置在图片上都有显示,只要按照这个规则来,就可以实现了。(a[0]不存储)
a[1]:根节点
a[2]:根的左孩子
a[3]:根的右孩子
以此类推

另外不要忘了按行遍历,因为这样数组顺序和按行遍历的顺序刚好是相同的(对于完全二叉树)
而如果非完全二叉树,这样是不是就不行了?
之前说过,如果非完全,可以考虑将缺失的位置标记(假设有这些结点,然后按照完全二叉树构造)
在这里插入图片描述
在这里插入图片描述
(第二个图的12结点就应该在数组中排13,12的位置做一下特殊标记就行了)

二叉树的指针存储

因为只有两个孩子结点,而不是普通的树那样,不知道有多少结点导致可能有大量的指针为空。

typedef struct Btree//树的结构体
{
    char data;
    struct Btree* lchild;
    struct Btree* rchild;
}btree;

这里面的数值域为char型变量,两个指针指向左右孩子不多说。

接下来一个很严肃的问题,二叉树应该怎么建立?
好问题(雾),我们还是采用递归的方式:

btree* setup()//建立二叉树
{
    btree *bt=NULL;
    char ch;
    cin>>ch;
    if(ch!='#')//#代表空,例如输入为ABDH##I##E##CF#J##G##
    {
        bt=new(btree);
        if(!bt)//存储空间不足
            exit(0);
        bt->data=ch;
        bt->lchild=setup();
        bt->rchild=setup();
    }
    return bt;
}

ABDH##I##E##CF#J##G##,这是一个案例,构成这样的一个树:
在这里插入图片描述
(行吧行吧,就长这样了,强迫症估计要疯了)
不管这个图长得多丑,以后都要见到很多次(因为ppt画一个要人命)

细心的人已经发现了,这个输入感觉怎么这么像二叉树的先序遍历?
确实,在回顾setup函数最后我们可以看出来根左右的顺序。

一些零碎的东西

感觉这部分在考试中可能有一些作用,另外如果是为了提升自我,看一下可能拓展思维。

一个结论:n个结点有n+1个空指针(和前面二叉树第四条性质有关,上一篇博客)

一个定理:完全二叉树的一个节点如果没有左孩子,则一定是叶子结点。(不可能没左孩子却有右孩子,或者从2i的角度考虑)

有n0个叶子的完全二叉树最多多少个结点?
n0=n2+1(下标代表度数)
总计为n0+n1+n2,而对于完全二叉树,(出)度为1的结点最多一个(参见上面的定理)
所以最多2n0个结点

设高为h的二叉树只有度为0和度为2的结点,则此类二叉树的结点数范围?
在这里插入图片描述
(第一种树还是很常见的,对于这个形状后期还有讨论)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值