自由树
有关自由树的研究是图论讨论的主要内容之一,这里不做讨论
有根树
简称树,它是 n ( n ≥ 0 ) n(n\ge 0) n(n≥0)个结点的有限集合。当 n = 0 n=0 n=0时,称为空树。
在任意一棵非空树中应满足:
树的定义是递归的,是一种递归的数据结构。树作为一种逻辑结构,同时也是一种分层结构,具有以下特点:
在 n n n个结点的树中有 n − 1 n-1 n−1条边
树的性质
结点——它包含数据项及指向其他结点的分支
结点的度——是结点拥有的子树棵树
叶结点——即度为0的结点,又称终端结点
分支结点——除叶结点以外的其他结点,又称非终端结点
子女结点
父结点
兄弟结点
祖先结点
子孙结点
结点所处层次
树的深度
树的高度
树的度
有序树
无序树
森林
路径和路径长度
与树相似,二叉树也以递归的形式定义。二叉树是 n ( n ≥ 0 ) n(n\ge0) n(n≥0)个结点的有限集合:
几种特殊的二叉树
二叉树的性质 王P109
顺序存储结构
完全二叉树可采用一维数组存储。
将完全二叉树自顶向下,从左往右编号,该编号即数组的下标。
这种方式是完全二叉树最简单最省存储的存储方式。
链式存储结构
由于顺序结构空间利用率低,因此二叉树一般都采用链式存储结构。
链表可采用二叉链表(只存左子结点和右子结点)和三叉链表(多存了父结点)
操作步骤
若二叉树为空,什么也不做
代码
void PreOrder (BiTree T){
if (T != NULL){
visit(T);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
操作步骤
若二叉树为空,什么也不做
代码
void InOrder(BiTree T){
if(T != NULL){
InOrder(T->lchild);
visit(T);
InOrder(T->rchild);
}
}
操作步骤
若二叉树为空,什么也不做
代码
void PostOrder(BiTree T){
if(T != NULL){
PostOrder(T->lchild);
PostOrder(T->rchild);
visit(T);
}
}
三种算法的时间复杂度都为 O ( n ) O(n) O(n)。在递归遍历中,递归工作栈的栈深恰好为树的深度,所以在最坏情况下,遍历算法的空间复杂度为 O ( n ) O(n) O(n)
为了把一个递归过程改为非递归过程,一般需要利用一个工作栈,记录遍历时的回退路径。
前序遍历的非递归算法
中序遍历的非递归算法
void InOrder2(BiTree T){
InitStack(S);
BiTree p = T;
while(p || !IsEmpty(S)){
if(p){
Push(S,p); //每遇到非空二叉树往左走
p = p->lchild;
}
else{
Pop(S,p);
visit(p); //退栈,访问根结点
p = p->rchild;
}
}
}
后序遍历的非递归算法
进行层次遍历,需要借助一个队列。先将二叉树根结点入队,然后出队,访问该结点,若它有左子树,则将左子树根结点入队;若它有右子树,则将右子树根结点入队。然后出队,对出队结点访问,如此反复,直到队列为空。
void LevelOrder(BiTree T){
InitQueue(Q);
BiTree p;
EnQueue(Q,T);
while(!IsEmpty(Q)){
DeQueue(Q,p);
visit(p);
if(p->lchild != NUll)
EnQueue(Q,p->lchild);
if(P->rchild != NULL)
EnQueue(Q,p->rchild);
}
}
由二叉树的前序序列和中序序列可以唯一地确定一棵二叉树,同理由后序序列和中序序列也可以唯一确定一棵二叉树,而仅通过前序序列和后序序列不能唯一确定一棵二叉树。
由二叉树的层序序列和中序序列也可以唯一确定一棵二叉树。
引入线索二叉树是为了加快查找结点前驱和结点后继的速度。
王P120
双亲表示法
孩子表示法
孩子表示法是将每个孩子结点都用单链表链接起来形成一个线性结构,此时n个结点就有n个孩子链表。
孩子兄弟表示法
这种存储表示法比较灵活,其最大的优点是可以方便地实现树转换为二叉树的操作,易于查找结点的孩子等,…
树转换为二叉树的规则
每个结点左指针指向它第一个孩子结点,右指针指向它在树中的相邻兄弟结点,可表示为“左孩子右兄弟”。由于根结点没有兄弟,所以由树转换而得的二叉树没有右子树。
森林转换为二叉树的规则
先将森林中的每棵树转换为二叉树,再将第一棵树的根作为转换后二叉树的根,将第一棵树的左子树作为转换后二叉树根的左子树,将第二棵树作为转换后二叉树的右子树,将第三棵树作为转换后二叉树根的右子树的右子树,以此类推,就可以完成。
二叉树转换为森林的规则
若二叉树非空,则二叉树的根及其左子树为第一棵树的二叉树形式,二叉树根的右子树又可视为一个由除第一棵树外的森林转换后的二叉树,应用同样的方法,直到最后产生一棵没有右子树的二叉树为止,这样就得到了原森林。
树转换成二叉树的画法
森林转换为二叉树的画法
树的遍历
森林的遍历