二叉树的遍历有递归与非递归两种方式,但思想大致相同
前序:先打印然后遍历完他的左子树,左子树为空时开始返回,并且开始以栈中元素为根遍历右子树
中序:先遍历左子树然后左子树入栈,左子树为空再打印,再遍历右子树
后序:先遍历完左子树,左子树入栈保存,再遍历右子树,遍历完打印,否则继续入栈
递归遍历
//递归遍历
//遍历树
//前序
void PreOder1(Tree *root)
{
if (root == NULL)
{
printf("# ");
return;
}
printf("%c ", root->data);
PreOder1(root->leftchild);
PreOder1(root->rightchild);
}
//中序
void PreOder2(Tree *root)
{
if (root == NULL)
{
printf("# ");
return;
}
PreOder2(root->leftchild);
printf("%c ", root->data);
PreOder2(root->rightchild);
}
//后序
void PreOder3(Tree *root)
{
if (root == NULL)
{
printf("# ");
return;
}
PreOder3(root->leftchild);
PreOder3(root->rightchild);
printf("%c ", root->data);
}
非递归遍历
需要手动创建一个栈结构,然后进行,遍历入栈等操作
//非递归 前序遍历
void frountTree(Tree *root)
{
Tree *pCur=root;
Tree *pTop=NULL;
Stact TreeStack;
InitStack(&TreeStack);
while (!Empy(&TreeStack)||pCur!=NULL)
{
while (pCur != NULL)
{
printf("%c ", pCur->data);
Push(&TreeStack, pCur);
pCur = pCur->leftchild;
}
pTop = Pop(&TreeStack);
pCur = pTop->rightchild;
}
}
//中序
//栈顶元素为根,如果他不为空就入栈,他为空说明他的上一个节点没有左子,打印,然后出栈看他的右子
void midTree(Tree*root)
{
Tree* pCur = root;
Tree* pTop = NULL;
Stact TreeStack;
InitStack(&TreeStack);
while (!Empy(&TreeStack) || pCur != NULL)
{
while (pCur!= NULL)
{
Push(&TreeStack, pCur);
pCur = pCur->leftchild;
}
pTop = StackTop(&TreeStack);
printf("%c ", pTop->data);
pCur = pTop->rightchild;
Pop(&TreeStack);
}
}
//后序
void backTree(Tree*root)
{
Tree* pCur = root;
Tree* pTop = NULL;
Tree* pLast = NULL;//这个节点的右子树已经被访问过了
Stact TreeStack;
InitStack(&TreeStack);
while (!Empy(&TreeStack) || pCur != NULL)
{
while (pCur != NULL)
{
Push(&TreeStack, pCur);
pCur = pCur->leftchild;
}
pTop = StackTop(&TreeStack);
if (pTop->rightchild == NULL || pTop->rightchild == pLast) //pTop有右子树,但是已经被遍历过了/
{
//出栈打印
Pop(&TreeStack);
printf("%c ", pTop->data);
//pLast = StackTop(&TreeStack);
pLast = pTop;//打印过pTop说明已经遍历过,所以pLast=pTop,下一次pTop再出栈,如果pTop的右子树为pLast说明他被遍历过了
continue;
}
pCur = pTop->rightchild;
}
}