先序遍历
若二叉树为空,则什么也不做;否则,
1.访问根结点;
2.先序遍历左子树;
3.先序遍历右子树。
对应的递归算法如下:
void PreOrder(BiTree T){
if(T != NULL){
visit(T);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
中序遍历
若二叉树为空,则什么也不做;否则,
1.中序遍历左子树;
2.访问根结点;
3.中序遍历右子树。
对应的递归算法如下:
void InOrder(BiTree T){
if(T != NULL){
PreOrder(T->lchild);
visit(T);
PreOrder(T->rchild);
}
}
后序遍历
若二叉树为空,则什么也不做;否则,
1.后序遍历左子树;
2.后序遍历右子树;
3.访问根结点。
对应的递归算法如下:
void PostOrder(BiTree T){
if(T != NULL){
PreOrder(T->lchild);
PreOrder(T->rchild);
visit(T);
}
}
递归算法和非递归算法的转换
中序遍历的非递归算法如下:
void InOrder2(BiTree T){
InitStack(S); // 初始化栈S
BiTree(p = T); // p是遍历指针
while(p || !IsEmpty(S)){ // 栈不空或p不空时循环
if(p){ // 一路向左
push(S,p); // 当前结点入栈
p = p->lchild; // 左孩子不空,一直向左走
}else { // 出栈,并转向出栈结点的右子树
Pop(S,p); // 栈顶元素出栈
visit(p); // 访问出栈结点
p = p->rchild; // 向右子树走,p赋值为当前右孩子
}
}
}
先序遍历的非递归算法如下:
void PreOrder2(BiTree T){
InitStack(S); // 初始化栈S
BiTree(p = T); // p是遍历指针
while(p || !IsEmpty(S)){ // 栈不空或p不空时循环
if(p){ // 一路向左
visit(p); // 访问当前结点
push(S,p); // 当前结点入栈
p = p->lchild; // 左孩子不空,一直向左走
}else { // 出栈,并转向出栈结点的右子树
Pop(S,p); // 栈顶元素出栈
p = p->rchild; // 向右子树走,p赋值为当前右孩子
}
}
}
先序遍历的非递归算法如下:
void PostOrder2(BiTree T){
InitStack(S); // 初始化栈S
BiTree(p = T); // p是遍历指针
r = NULL; // 辅助指针
while(p || !IsEmpty(S)){ // 栈不空或p不空时循环
if(p){ // 一路向左
push(S,p); // 当前结点入栈
p = p->lchild; // 左孩子不空,一直向左走
}else { // 出栈,并转向出栈结点的右子树
GetTop(S,p); // 读栈顶结点(非出栈)
if(p->rchild && p->rchild != r) // 右子树存在,且未被访问过
p = p->rchild; 向右子树走,p赋值为当前右孩子
else{
Pop(S,p); // 栈顶元素出栈
visit(p->data); // 访问当前结点
r = p; // 记录最近访问过的结点
p = NULL; // 结点访问完后,重置p指针
}
}
}
}
层次遍历
借助一个队列。先将二叉树根结点入队,然后出队,访问出队结点,若它有左子树,则将左子树根结点入队;若它有右子树,则将右子树根节点入队。然后出队结点......如此反复,直至队列为空。
层次遍历算法如下:
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); // 右孩子不空,则右子树根结点入队
}
}
由遍历序列构造二叉树
1.先序序列和中序序列
2.后序序列和中序序列
3.层序序列和中序序列