二叉树的链式存储结构:
typedef struct BiTNode{
ElemType data; //数据域
struct BiTNode *lchild, *rchild; //左右孩子指针
}BiTNode,*BiTree;
先序(PreOrder)遍历(NLR):
void PreOrder (BiTree T){
if(T!=NULL){
visit(T); //访问根节点
PreOrder(T->lchild); //递归遍历左子树
PreOrder(T->rchild); //递归遍历右子树
}
}
中序(InOrder)遍历(LNR):
void InOrder(BiTree T){
if(T!=NULL){
InOrder(T->lchild);
visit(T);
InOrder(T->rchild);
}
}
后序(PostOrder)遍历(LRN):
void PostOrder(BiTree T){
if(T!=NULL){
PostOrder(T->lchild);
PostOrder(T->rchild);
visit(T);
}
}
中序遍历(LNR)的非递归算法:
void InOrder2(BiTreeT){
InitStack(S);
BiTree p=T; //p是遍历指针
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); //右子树不空,右子树根节点入队
}
}
线索二叉树:
在以一种方式遍历二叉树时,充分利用二叉树的空余的区域,空域区域若是左孩子,那么指向前驱,否则指向后继。
线索二叉树存储结构:
typedef struct ThreadNode{
ElemType data;
struct ThreadNode *lchild,*rchild;
int ltag,rtag; //0表示左/右有元素,1则反之
}ThreadNode,*THreadTree;
中序遍历线索化二叉树递归算法:
void InThread(ThreadTree &p,ThreaTree &pre){
if(p!=NULL){
InThread(p->lchild,pre); //递归,线索化左子树
if(p->lchild==NUll){ //左子树为空,建立前驱线索
p->lchild=pre;
p->ltag=1;
}
if(pre!=NULL&&pre->rchild==NULL){
pre->rchild=p; //建立前驱结点的后续线索
pre->rtag=1;
}
pre=p; //标记当前结点成为刚刚访问过的结点
InThread(p->rchild,pre); //递归,线索化右子树
}
}
树转换成二叉树的规则:
每个结点左指针指向它的第一个孩子,右指针指向它在树中的相邻右兄弟,这个规则又称“左孩子右兄弟”。
树转换成二叉树的画法:
1. 在兄弟结点之间加一连线;
2. 对每个节点,只保留它与第一个孩子的连线,而与其他孩子的连线全部抹掉;
3. 以树根为轴心,顺时针旋转45°。
森林换成二叉树的画法:
1. 将森林中的没课树转换成相应的二叉树;
2. 每棵树的跟也可以视为兄弟关系,在每棵树的根之间加一根连线;
3. 以第一棵树的根为轴心顺时针旋转45°。