基本术语
结点node:一个数据元素及其若干指向其子树的分支
结点的度,树的度degree:结点所拥有的子树的棵数称为结点的度,结点度的最大值称为树的度
叶子结点,非叶子结点left:度为0的点称为叶子结点(或终端结点),度不为0的点称为非叶子节点(或分支结点)
孩子结点,双亲结点,兄弟结点:一个结点的子树的根称为该节点的孩子节点或子节点,相应地,该结点是其孩子节点的双亲节点或父节点
层次、堂兄弟结点:双亲节点在同一层的所有节点称为堂兄弟结点,规定根结点层次为1,其余结点层次等于其双亲结点层次加1
结点的层次路径、祖先、子孙:
从根节点开始,到达某结点p所经过的所有结点称为结点p的层次路径
结点p的层次路径上的所有结点称为p的祖先
以某一结点为根的子树中的任意节点称为该结点的子孙结点
树的深度:树中结点的最大层次值
有序树和无序树:对于一棵树,若其中每一个结点的子树(若有)具有一定的次序,则称该树为有序树,否则为无序树
森林:是m棵互不相交的树的集合。显然,若将一棵树的根结点删除,剩余的子树就构成了森林。
二叉树的定义和性质
二叉树是一种树型结构,它的特点是每个结点至多有两棵子树(即二叉树中不存在度大于2的结点),并且,二叉树的子树有左右之分,其次序不能任意颠倒。
二叉树的五个性质
性质1 在二叉树的第i层至多有
2
i
−
1
{2^{i-1}}
2i−1个结点
(
i
≥
1
)
(i\ge1)
(i≥1)
性质2 深度为k的二叉树至多有
2
k
−
1
2^k-1
2k−1个结点
(
k
≥
1
)
(k\geq1)
(k≥1)
性质3 对任何一棵二叉树T,如果其终端结点数为
n
0
n_0
n0,度为2的结点数为
n
2
n_2
n2,则
n
0
=
n
2
+
1
n_0=n_2+1
n0=n2+1
性质4 具有n个结点的完全二叉树的深度为
⌊
l
o
g
2
n
⌋
+
1
\lfloor log_2n \rfloor+1
⌊log2n⌋+1
性质5 如果对一棵有n个结点的完全二叉树(其深度为
⌊
l
o
g
2
n
⌋
+
1
\lfloor log_2n \rfloor+1
⌊log2n⌋+1)的结点按层序编号(从第1层到第
⌊
l
o
g
2
n
⌋
+
1
\lfloor log_2n \rfloor+1
⌊log2n⌋+1层,每层从左到右),则对于任一结点
i
(
1
≤
i
≤
n
)
i(1\leq i\leq n)
i(1≤i≤n),有
(1)如果
i
=
1
i=1
i=1,则结点i是二叉树的根,无双亲;如果
i
>
1
i>1
i>1,则其双亲结点是
⌊
i
/
2
⌋
\lfloor i/2 \rfloor
⌊i/2⌋
(2)如果
2
i
>
n
2i>n
2i>n,则结点i无左孩子(结点i为叶子结点);否则其左孩子是结点
2
i
2i
2i
(3)如果
2
i
+
1
>
n
2i+1>n
2i+1>n,则结点i无右孩子(结点i为叶子结点);否则其右孩子是结点
2
i
+
1
2i+1
2i+1
二叉树的链式存储结构
typedef struct BiTNode{
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
BiTree CreateTree(int k){
BiTree T;
if(k<=10){
T=(BiTNode*)malloc(sizeof(BiTNode));
T->data=a[k];
T->lchild=NULL;
T->rchild=NULL;//这两行一定要加
}
return T;
}
递归遍历
先序遍历
void PreOrder(BiTree T){
if(T!=NULL){
visit(T);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
中序遍历
void InOrder(BiTree T){
if(T!=NULL){
PreOrder(T->lchild);
visit(T);
PreOrder(T->rchild);
}
}
后序遍历
void PostOrder(BiTree T){
if(T!=NULL){
PreOrder(T->lchild);
PreOrder(T->rchild);
visit(T);
}
}
完整代码
#include <stdio.h>
#define TElemType int
typedef struct BiTNode{
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
int a[100]={10,9,2,11,91,20,1,30,20,39};
void visit(BiTree T){
printf("%d ",T->data);
}
BiTree CreateTree(int k){
BiTree T;
if(k<=10){
T=(BiTNode*)malloc(sizeof(BiTNode));
T->data=a[k];
T->lchild=NULL;
T->rchild=NULL;
}
return T;
}
void InOrder(BiTree T){
if(T!=NULL){
PreOrder(T->lchild);
visit(T);
PreOrder(T->rchild);
}
}
void PreOrder(BiTree T){
if(T!=NULL){
visit(T);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
void PostOrder(BiTree T){
if(T!=NULL){
PreOrder(T->lchild);
PreOrder(T->rchild);
visit(T);
}
}
BiTree first;
int main(){
first=(BiTNode*)malloc(sizeof(BiTNode));
first->data=a[1];
first->lchild=CreateTree(2);
first->rchild=CreateTree(3);
printf("\n后序遍历:");
PostOrder(first);
printf("\n先序遍历:");
PreOrder(first);
printf("\n中序遍历:");
InOrder(first);
return 0;
}
非递归遍历
先序遍历
void PreOrder(BiTree T){
BiTree Stack[100];
int top=0;
BiTree P=T;
while(P!=NULL||top!=0){
if(P){
visit(P);
Stack[top]=P;
top++;
P=P->lchild;
}
else{
P=Stack[top-1];
top--;
P=P->rchild;
}
}
}
中序遍历
void InOrder(BiTree T){
InitStack(S);
BiTree P=T;
while(P!=NULL||!empty(S)){
if(P){
Push(P);
P=P->lchild;
}
else{
Pop(S,P);
visit(P);
P=P->rchild;
}
}
}
后序遍历
void PostOrder(BiTree T){
BiTree P=T;
BiTree r=NULL;
BiTree Stack[100];
int top=0;
while(P!=NULL||top!=0){
if(P){
Stack[top]=P;
top++;
P=P->lchild;
}
else{
P=Stack[top-1];
if(P->rchild&&P->rchild!=r) P=P->rchild;
else{
P=Stack[top-1];
top--;
visit(P);
r=P;
P=NULL;
}
}
}
}
完整代码
#include <stdio.h>
#include <stdlib.h>
#define TElemType int
typedef struct BiTNode{
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
int a[100]={10,9,2,11,91,20,1,30,20,39};
void visit(BiTree T){
printf("%d ",T->data);
}
BiTree CreateTree(int k){
BiTree T;
if(k<=10){
T=(BiTNode*)malloc(sizeof(BiTNode));
T->data=a[k];
T->lchild=NULL;
T->rchild=NULL;
}
return T;
}
void InOrder(BiTree T){
BiTree Stack[100];
int top=0;
BiTree P=T;
while(P!=NULL||top!=0){
if(P){
Stack[top]=P;
top++;
P=P->lchild;
}
else{
P=Stack[top-1];
top--;
visit(P);
P=P->rchild;
}
}
}
void PostOrder(BiTree T){
BiTree P=T;
BiTree r=NULL;
BiTree Stack[100];
int top=0;
while(P!=NULL||top!=0){
if(P){
Stack[top]=P;
top++;
P=P->lchild;
}
else{
P=Stack[top-1];
if(P->rchild&&P->rchild!=r) P=P->rchild;
else{
P=Stack[top-1];
top--;
visit(P);
r=P;
P=NULL;
}
}
}
}
void PreOrder(BiTree T){
BiTree Stack[100];
int top=0;
BiTree P=T;
while(P!=NULL||top!=0){
if(P){
visit(P);
Stack[top]=P;
top++;
P=P->lchild;
}
else{
P=Stack[top-1];
top--;
P=P->rchild;
}
}
}
BiTree first;
int main(){
first=(BiTNode*)malloc(sizeof(BiTNode));
first->data=a[1];
first->lchild=CreateTree(2);
first->rchild=CreateTree(3);
printf("\n后序遍历:");
PostOrder(first);
printf("\n先序遍历:");
PreOrder(first);
printf("\n中序遍历:");
InOrder(first);
return 0;
}
层次遍历
void LevelOrder(BiTree T){
BiTree Queue[100];
int l=0,r=0;
BiTree P=T;
while(P&&l<=r){
visit(P);
if(P->lchild){
Queue[r]=P->lchild;
r++;
}
if(P->rchild){
Queue[r]=P->rchild;
r++;
}
P=Queue[l];
l++;
}
}