数据结构6.2_二叉树
1、二叉树的定义:
二叉树(Binary True)是另一种树型结构,它的特点是每个结点至多只有两棵子树(即二叉树中不存在度大于2的结点),并且,二叉树的子树有左右之分,其次序不能任意颠倒。
以下是二叉树的五种基本形态:
2、二叉树的性质:
二叉树的结构特点和性质:https://blog.csdn.net/qq_34322188/article/details/82346068
二叉树的性质有三条:
1)性质1:在二叉树的第i层上至多有2^(i-1)个结点(i>=1); //利用归纳法可以证明
2)性质2:深度为k的二叉树至多有2^k - 1个结点(k >= 1); //可以利用性质1证明
3)性质3:对于任何二叉树T,如果其终端结点的个数为n0,度为2的结点树为n2,则n0=n2+1; //可以从二叉树的分支数量B=n1+n2,n1是度为1的结点;所有结点的度不超过2,n=n0+n1+n2;去证明;
完全二叉树 和 满二叉树 是两种形态特殊的二叉树。
浅谈数据结构-二叉树:https://www.cnblogs.com/polly333/p/4740355.html
通过观察上图可以发现,完全二叉树的所有编号与结点可以与满二叉树的编号一一对应。
完全二叉树的特点是:
1)叶子结点只可能在层次最大的两层出现;
2)对任一结点,若其右分支下的子孙的最大层次为l,则其左分支下的子孙的最大层次必为l或l+1;
完全二叉树将在很多场合下出现,下面将介绍完全二叉树的两个重要特性:
1)特性1:具有n的结点的完全二叉树的深度为log2n+1
满二叉树是完全二叉树,对于深度为k的满二叉树中结点数量是2k-1 = n,完全二叉树结点数量肯定最多2k-1,
同时完全二叉树倒数第二层肯定是满的(倒数第一层有结点,那么倒是第二层序号和满二叉树相同),所以完全二叉树的结点数最少大于少一层的满二叉树,为2k-1-1。
根据上面推断得出: 2k-1-1< n=<2k-1,因为结点数Nn为整数那么n<=2k-1可以推出n<=2k ,n>2k-1-1可以推出 n>=2k-1,所以2k-1<n<=2k 。即可得k-1<=log2n<k 而k作为整数因此k=[log2n]+1。
2)特性2:如果有一颗有n个节点的完全二叉树的节点按层次序编号,对任一层的节点i(1<=i<=n)有
1.如果i=1,则节点是二叉树的根,无双亲,如果i>1,则其双亲节点为[i/2],向下取整
2.如果2i>n那么节点i没有左孩子,否则其左孩子为2i
3.如果2i+1>n那么节点没有右孩子,否则右孩子为2i+1
这个三条子特性用于求任意节点的左右孩子;很有用;
具体证明略过,可以查看上述链接中的验证。
3、二叉树的存储结构:
二叉树的存储结构:https://www.cnblogs.com/yw-ah/p/5872516.html
二叉树是非线性结构,即每个数据结点至多只有一个前驱,但可以有多个后继。它可采用顺序存储结构和链式存储结构。
3.1顺序存储结构
二叉树的顺序存储,就是用一组连续的存储单元存放二叉树中的结点。
因此,必须把二叉树的所有结点安排成为一个恰当的序列,结点在这个序列中的相互位置能反映出结点之间的逻辑关系,用编号的方法从树根起,自上层至下层,每层自左至右地给所有结点编号,
缺点是有可能对存储空间造成极大的浪费,在最坏的情况下,一个深度为k且只有k个结点的右单支树需要2k-1个结点存储空间。
依据二叉树的性质,完全二叉树和满二叉树采用顺序存储比较合适,树中结点的序号可以唯一地反映出结点之间的逻辑关系,
这样既能够最大可能地节省存储空间,又可以利用数组元素的下标值确定结点在二叉树中的位置,以及结点之间的关系。
1 #define Maxsize 100 //假设一维数组最多存放100个元素 2 typedef char Datatype; //假设二叉树元素的数据类型为字符 3 typedef struct 4 { Datatype bt[Maxsize]; 5 int btnum; 6 }Btseq;
3.2链式存储结构
二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。
通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址。其结点结构为:
其中,data域存放某结点的数据信息;lchild与rchild分别存放指向左孩子和右孩子的指针,当左孩子或右孩子不存在时,相应指针域值为空(用符号∧或NULL表示)。利用这样的结点结构表示的二叉树的链式存储结构被称为二叉链表,
为了方便访问某结点的双亲,还可以给链表结点增加一个双亲字段parent,用来指向其双亲结点。每个结点由四个域组成,其结点结构为:
这种存储结构既便于查找孩子结点,又便于查找双亲结点;但是,相对于二叉链表存储结构而言,它增加了空间开销。利用这样的结点结构表示的二叉树的链式存储结构被称为三叉链表。
尽管在二叉链表中无法由结点直接找到其双亲,但由于二叉链表结构灵活,操作方便,对于一般情况的二叉树,甚至比顺序存储结构还节省空间。因此,二叉链表是最常用的二叉树存储方式。
1 #define datatype char //定义二叉树元素的数据类型为字符 2 typedef struct node //定义结点由数据域,左右指针组成 3 { Datatype data; 4 struct node *lchild,*rchild; 5 }Bitree;