树的遍历有三种形式:1. 前序遍历 2. 中序遍历 3. 后序遍历。
每种形式的遍历的方式又可以分为递归与非递归两种。
递归遍历中,三种方式递归的路径均相同,区别仅仅是访问结点时间的不同而已。
非递归遍历中,通过栈来实现递归的作用,其中,后序非递归遍历最为复杂,需要记录结点访问次数。
六种遍历方式完整代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <iostream>
#include <stack>
using namespace std;
typedef struct binode{
char ch;
struct binode *lchild, *rchild;
} *bitree;
/* 该结构体用于后序非递归遍历 */
typedef struct binode2{
bitree bt2;
bool FirstTime;
} *bitree2;
/* 前序创建树 */
void CreatBitree(bitree &bt)
{
char val;
scanf("%c", &val);
if(val == ' ')
bt = NULL;
else {
if(!(bt = (bitree)malloc(sizeof(struct binode))))
exit(1);
bt->ch = val;
CreatBitree(bt->lchild);
CreatBitree(bt->rchild);
}
}
/* 前序递归遍历 */
void PreOrderTraverse(bitree bt)
{
if(bt) {
printf("%c ", bt->ch);
PreOrderTraverse(bt->lchild);
PreOrderTraverse(bt->rchild);
}
}
/* 中序递归遍历 */
void InOrderTraverse(bitree bt)
{
if(bt) {
InOrderTraverse(bt->lchild);
printf("%c ", bt->ch);
InOrderTraverse(bt->rchild);
}
}
/* 后序递归遍历 */
void PostOrderTraverse(bitree bt)
{
if(bt) {
PostOrderTraverse(bt->lchild);
PostOrderTraverse(bt->rchild);
printf("%c ", bt->ch);
}
}
/* 前序非递归遍历 */
void PreTry(bitree bt)
{
stack<bitree> s;
while(bt != NULL || !s.empty()) {
while(bt != NULL) {
printf("%c ", bt->ch);
s.push(bt);
bt = bt->lchild;
}
if(!s.empty()) {
bt = s.top();
s.pop();
bt = bt->rchild;
}
}
}
/* 中序非递归遍历 */
void InTry(bitree bt)
{
stack<bitree> s;
while(bt != NULL || !s.empty()) {
while(bt != NULL) {
s.push(bt);
bt = bt->lchild;
}
if(!s.empty()) {
bt = s.top();
printf("%c ", bt->ch);
s.pop();
bt = bt->rchild;
}
}
}
/* 后序非递归遍历 */
void PostTry(bitree bt)
{
stack<bitree2> s;
bitree2 btp;
bitree2 p;
while(bt != NULL || !s.empty()) {
while(bt != NULL) {
if(!(btp = (bitree2)malloc(sizeof(struct binode2))))
exit(1);
btp->bt2 = bt;
btp->FirstTime = true;
s.push(btp);
bt = bt->lchild;
}
if(!s.empty()) {
p = s.top();
s.pop();
if(p->FirstTime == true) { //设置标志位用于记录访问次数
p->FirstTime = false;
s.push(p);
bt = p->bt2->rchild;
}
else {
printf("%c ", p->bt2->ch);
// bt = NULL;
}
}
}
}
int main()
{
bitree bt;
CreatBitree(bt);
PreOrderTraverse(bt);
printf("\n");
PreTry(bt);
printf("\n");
InOrderTraverse(bt);
printf("\n");
InTry(bt);
printf("\n");
PostOrderTraverse(bt);
printf("\n");
PostTry(bt);
printf("\n");
while(1);
return 0;
}