一、二叉树的存储结构
顺序存储
#define Maxsize 100
struct TreeNode{
ElemType value; //结点中的数据元素
bool isEmpty; //结点是否为空
};
TreeNode t[Maxsize]; //定义一个数组t,按照从上至下,从左至右的顺序依次存储完全二叉树的结点
for(int i=0;i<Maxsize;i++){
t[i].isEmpty=true;
}
链式存储
struct ElemType{
int value;
}
typedef struct BiTNode{
ElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
//定义一棵树
BiTree root=NULL;
//插入根节点
root=(BiTree)malloc(sizeof(BiTNode));
root->data={1};
root->lchild=NULL;
root->rchild=NULL;
//插入新结点
BiTNode *p=(BiTNode *)malloc(sizeof(BiTNode));
p->data={2};
p->lchild=NULL;
p->rchild=NULL;
root->lchild=p; //作为根节点的左孩子
二、二叉树的遍历
先序遍历(根左右)
可对应于前缀表达式
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);
}
}
层次遍历
//二叉树的结点(链式存储)
typedef struct BiTNode{
ElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
//链式队列结点
typedef struct LinkNode{
BiTNode * data;
struct LinkNode *next;
}LinkNode;
typedef struct{
LinkNode * front,*rear;
}LinkQueue;
void LevelOrder(BiTree T){
LinkQueue Q;
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);
}
}
三、二叉树的应用
求树的深度
int treeDepth(BiTree T){
if(T ==NULL){
return 0;
}
else{
int l=treeDepth(T->lchild);
int r=treeDepth(T->rchild);
//树的深度=MAX(左子树深度,右子树深度)+1
return l>r ? l+1:r+1;
}
}
注意
二叉树的中序遍历序列
Q1:如何找到指定结点p在中序遍历序列中的前驱
Q2:如何找到p的中序后继
思路:
从根节点出发,重新进行一次中序遍历,指针q访问当前访问的结点,指针pre记录上一个被访问的结点
(1)当q= =p时,pre是前驱
(2)当pre= =p时,q为后继