树和二叉树
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
树和二叉树
树形结构(非线性结构):1)节点之间有分支;2)具有层次关系。
应用:自然界的树;人类社会的家谱和行政组织机构;计算机中的编译(用树表示源程序的语法结构)、数据库系统(用树组织信息)、算法分析(用树描述执行过程)。
定义:是n(n>=0)个节点的有限集。
若n=0,称为空树;
若n>0,则它满足如下两个条件;
1)有且仅有一个特定的称为根的节点;
2)其余节点可分为m(m>=0)个互不相交的有限集T1,T2,T3.....Tm,其中每一个集合本身又是一棵树,并称为根的子树。
树的其他表示方式:
还可以用广义表的形式表示(A(B(D))(C(E)(F)))。
树的基本术语:
根节点:非空树中无前驱节点的节点。
节点的度:节点拥有的子树数。
树的度:树内各节点的度的最大值。
叶子(终端节点):度为0的节点
分支节点(非终端节点):根节点以外的分支节点称为内部节点。
孩子、双亲:节点的子树的根称为该节点的孩子,该节点称为孩子的双亲。
兄弟节点:
节点的祖先:从根节点所经分支上的所有节点。 节点的子孙:以某节点为根的子树中的任一节点。 树的深度(高度):树中最大层次(根节点为第一层)。 有序树:树中节点的各子树从左至右有次序() 无序树:树中的节点没有次序。
森林:是m (m>=0)棵互不相交的树的集合。一棵树可以看成是一个特殊的森林。给森林中的各子树加上一个双亲节点,森林就变成了树(树一定是森林,森林不一定是树)。
二叉树的性质和存储结构
性质1、在二叉树的第i 层上至多有2^(i -1)个节点(i>=1)。至少1个
归纳基:当i=1时,只有一个根节点,2^(i -1)=2^0=1,命题成立。 归纳假设:设对所有的j (1<=j
归纳证明:由归纳假设可知,第i -1层上至多有2^(i -2)个节点。由于二叉树每个节点的度最大为2,故在第i 层上最大节点数为第i -1层上最大节点数的2倍,即:2*2^(i -2)=2^(i -1)。证毕。
性质2、深度为K 的二叉树至多有2^k -1个节点(k>=1)。至少有k 个节点
由性质1可见,深度为k 的二叉树的最大节点数为
∑
=-k
i i 1
)1(^2=2^k -1
性质3:对任何一棵二叉树T ,如果其终端节点数为n0,度为2的节点数为n2,则 n0=n2+1。
总边数为B ,B=n -1; B=n2*2+n1*1; n=n2*2+n1*1+1 总节点数为n ,n=n2*2+n1*1+1; 又 n0=n2+1
满二叉树
·一棵深度为k 且有2^k -1个节点的二叉树称为满二叉树。
·特点:1)每一层上的节点数都是最大节点数(即每层都满,不能空的);2)叶子节点全部在最底层。
·对满二叉树节点位置进行编号:
·编号规则:从根节点开始,自上而下,自左而右。 ·每一节点位置都有元素。 ·满二叉树在同样深度的二叉树中节点个数最多;满二叉树在同样深度的二叉树中叶子节点个数最多。
完全二叉树
定义:深度为k的具有n个节点的二叉树,当且仅当其每一个节点都与深度为k的满二叉树中编号为1~n的节点一一对应时(1~n之间的节点不能断),称之为完全二叉树。
注:在满二叉树中,从最后一个节点开始,连续去掉任意个节点,即是一个完全二叉树。
特点:1、叶子节点只可能分布在层次最大的两层上。
2、对任一节点,如果其右子树的最大层次为i,则其左子树的最大层次必为i
或i+1.
完全二叉树的性质
性质4:具有n个节点的完全二叉树的深度为。
公式为取3,3+1=4;所以有4层
性质4表明了完全二叉树节点数n与完全二叉树深度k之间的关系。
性质5:如果对一棵有n个节点的完全二叉树(深度为[log2n]+1),节点按层序编号(从第1层到第[log2n]+1层,每层从左到右),则对任一节点i(1<=i<-n),有:
1)如果i=1,则节点i是二叉树的根,无双亲;如果>1,则其双亲是节点[i/2]。
2)如果2*i>n,则节点i为叶子节点,无左孩子;否则,其左孩子是节点
性质5表明了完全二叉树中双亲节点编号与孩子节点编号之间的关系
二叉树的顺序存储
实现:按满二叉树的节点层次编号,依次存放二叉树中的数据元素。
//二叉树的顺序存储表示
#define MAXSIZE 100
typedef int SqBitree[MAXSIZE]//这里将树的存储类型定义为int型
SqBitree bt;
缺点:最坏情况深度为k的且有k个节点的单支树需要长度为2^k-1的一维数组。
特点:节点间关系蕴含在其存储位置中浪费空间,适于存满二叉树和完全二叉树。
二叉树的链式存储结构
//二叉链表存储结构
typedef struct BiNode{
int data;
struct BiNode *Lchild ,*Rchild;
}BiNode,*BiTree;
在n个节点的二叉链表中,有n+1个空指针,分析:总共必有2*n个链域,其中除了根节点外每个节点都有一条链域与前驱相连,所以共消耗n-1个链域,因此,空指针为2*n-(n-1)=n+1(个)
三叉链表:
typedef struct TriTNode{
int data;
struct TriTNode *Lchild ,*Rchild,*parent;
}TriTNode,*TriTree;
遍历二叉树
遍历定义:顺着某一条搜索路径寻访二叉树中的节点,使得每个节点均被访问一次,而且仅被访问一次(又称周游)。-----”访问”的含义很广,可以是对节点作各种处理,如:输出节点的信息、修改节点的数据值等,但要求这种访问不破坏原来的数据结构。
遍历目的:得到树中所有节点的一个线性排列。
遍历用途:它是树结构插入、删除、修改、查找和排序运算的前提,是二叉树一切运算的基础和核心。
遍历二叉树的算法描述:
根据遍历序列确定二叉树
·若二叉树中各节点的值均不相同,则二叉树节点的先序序列、中序序列和后序序列都是唯一的。
·有二叉树的先序序列(先序遍历,根节点不在序列头部)和中序序列,或有二叉树的后序序列和中序序列(后序遍历,根节点必在后序序列尾部)可以确定唯一一颗二叉树。有先序和后序就不行。
【算法5.1】遍历
//先序遍历递归,后序和中序改变顺序即可
int preorder(Bitree t){
if(t==null) return 0;//空二叉树