简单遍历
- 先序遍历(DLR)
若二叉树不空,则:
(1)访问根结点;
(2)先序遍历左子树;
(3)先序遍历右子树。 - 中序遍历(LDR)
若二叉树不空,则:
(1)中序遍历左子树;
(2)访问根结点;
(3)中序遍历右子树。 - 后序遍历(LRD)
若二叉树不空,则:
(1)后序遍历左子树;
(2)后序遍历右子树;
(3)访问根结点。
- 二叉树递归遍历程序
#include <stdio.h>
#include <malloc.h>
using namespace std;
typedef struct Node
{
char data;
struct Node *Lchild;
struct Node *Rchild;
}BiTNode, *BiTree;
//前序遍历(根左右)
void PrePrint(BiTree T)
{
if (T != NULL)
{
printf("%c ", T->data);
PrePrint(T->Lchild);
PrePrint(T->Rchild);
}
}
//中序遍历(左根右)
void MidPrint(BiTree T)
{
if (T != NULL)
{
MidPrint(T->Lchild);
printf("%c ", T->data);
MidPrint(T->Rchild);
}
}
//后序遍历(左右根)
void LatePrint(BiTree T)
{
if (T != NULL)
{
LatePrint(T->Lchild);
LatePrint(T->Rchild);
printf("%c ", T->data);
}
}
//按照先序遍历创建二叉树
void PreCreateBiTree(BiTree *Troot)
{
char input;
scanf_s("%c", &input);
//孩子结点为空的部分用.代替
if (input == '.')
{
*Troot = NULL;
}
else
{
(*Troot) = (BiTree)malloc(sizeof(BiTNode));
(*Troot)->data = input;
PreCreateBiTree(&((*Troot)->Lchild));
PreCreateBiTree(&((*Troot)->Rchild));
}
}
int main(void)
{
BiTree T;
printf("请输入数据建立二叉树(孩子结点为空的部分用‘.’代替): \n");
PreCreateBiTree(&T);
printf("\n递归算法前序遍历的结果:");
PrePrint(T);
printf("\n递归算法中序遍历的结果:");
MidPrint(T);
printf("\n递归算法后序遍历的结果:");
LatePrint(T);
printf("\n\n");
return 0;
}
二叉树非递归遍历
在二叉树的非递归遍历中,需要借助栈来存储结点,先序和中序遍历与简单遍历理解相同,但在循环条件中也要注意判定栈是否为空才能进行栈的出入操作。
需要注意的是,在后序遍历中,根结点是最后被访问的。因此,在遍历过程中,当搜索指针指向某一根结点时,不能立即访问,而要先遍历其左子树,此时根结点进栈。当其左子树遍历完后再搜索到该根结点时,还是不能访问,还需遍历其右子树。所以,此根结点还需再次进栈,当其右子树遍历完后再退栈到到该根结点时,才能被访问。
二叉树递归遍历程序
#include <stdio.h>
#include <malloc.h>
#include <stack>
using namespace std;
typedef struct Node
{
char data;
struct Node *Lchild;
struct Node *Rchild;
}BiTNode, *BiTree;
//按照先序遍历创建二叉树
void PreCreateBiTree(BiTree *Troot)
{
char input;
scanf_s("%c", &input);
//孩子结点为空的部分用.代替
if (input == '.')
{
*Troot = NULL;
}
else
{
(*Troot) = (BiTree)malloc(sizeof(BiTNode));
(*Troot)->data = input;
PreCreateBiTree(&((*Troot)->Lchild));
PreCreateBiTree(&((*Troot)->Rchild));
}
}
//非递归先序遍历二叉树(根左右)
void New_PrePrint(BiTree Troot)
{
stack<BiTree> s;
BiTree root;
root = Troot;
while (root != NULL||!s.empty()) //当根结点不为空或者栈中有元素时不断遍历
{
if (root != NULL)
{
printf("%c ", root->data); //打印访问到的结点
s.push(root);
root = root->Lchild; //开始访问左孩子
}
else
{
root = s.top(); //当访问到的左结点为空时,使其返回到其父结点的位置
s.pop(); //该位置的值无用,从栈中弹出
root = root->Rchild; //开始访问右孩子
}
}
}
//非递归中序遍历二叉树(左根右)
void New_MidPrint(BiTree Troot)
{
stack<BiTree> s;
BiTree root;
root = Troot;
while (root != NULL||!s.empty())
{
if (root != NULL)
{
s.push(root); //先将访问到的元素存入栈中
root = root->Lchild; //不断访问左孩子
}
else
{
root = s.top(); //当访问到的左结点为空时,使其返回到其父结点的位置
s.pop();
printf("%c ", root->data); //打印这个没有左孩子的点。然后开始访问它的右孩子
root = root->Rchild;
}
}
}
//非递归后序遍历二叉树(左右根)
void New_LatePrint(BiTree Troot)
{
stack<BiTree> s;
BiTree root, old;
root = Troot;
old = NULL; //记录已被访问过的结点
while (root != NULL||!s.empty())
{
while (root != NULL)
{
//将访问到的左孩子不断压入栈中
s.push(root);
root = root->Lchild;
}
if (!s.empty())
{
root = s.top(); //使top指向刚才所访问结点的父结点
//先判断当前结点是否可以输出,再访问其右孩子
//如果该结点没有右孩子,或者其右孩子已被访问过,则可以输出
if (root->Rchild == NULL || root->Rchild == old)
{
printf("%c ", root->data);
old = root; //将当前结点设置为已访问过
s.pop();
root = NULL;
}
//当前结点不能输出,则继续访问其右孩子
else
{
root = root->Rchild;
}
}
}
}
int main(void)
{
BiTree T;
printf("请输入数据建立二叉树(孩子结点为空的部分用‘.’代替): \n");
PreCreateBiTree(&T);
printf("\n非递归算法前序遍历的结果:");
New_PrePrint(T);
printf("\n非递归算法中序遍历的结果:");
New_MidPrint(T);
printf("\n非递归算法后序遍历的结果:");
New_LatePrint(T);
printf("\n\n");
return 0;
}
根据给出的先序、中序序列画出二叉树
二叉树有四个节点,先序输出序列1234,后序输出序列4321,请画出所有可能的二叉树。
一棵树的先序序列为EBADCFHGIKJ,中序序列为ABCDEFGHIJK,请画出该二叉树,并输出该二叉树的后序序列。