二叉树的数组存储
有一说一,看到这个很多人应该是诧异的,因为就二叉树那个尿性 ,一对多的性质,如果是使用数组存储,线性表和一个二维性质的图形怎么能对应上?
这就要提到上一篇树的博客的一个性质(说过在存储会用上的)
因为每一个结点(除根节点)都有双亲结点,也可能有孩子结点,他们的位置在图片上都有显示,只要按照这个规则来,就可以实现了。(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的结点,则此类二叉树的结点数范围?
(第一种树还是很常见的,对于这个形状后期还有讨论)