






C语言版本,参考博客:二叉树遍历方法——前、中、后序遍历(图解)
#define _CRT_SECURE_NO_WARNINGS
/*引入头文件*/
#include
#include
#include
#include
#define Maxsize 100
typedef char Elemtype;
typedef struct BiTNode /*定义二叉树链式存储结构*/
{
Elemtype data;
struct BiTNode *lchild, *rchild;
}BiTNode,*BiTree;
typedef struct Stack /*定义堆栈存储结构*/
{
BiTree data[Maxsize];
int top;
}SqStack;
/*设置字体颜色*/
void color(short x);
/*测试菜单*/
int TestMeanu(void);
/*初始化堆栈*/
void InitStack(SqStack* S);
/*判断栈空*/
bool IsEmpty(SqStack S);
/*入栈*/
bool Push(SqStack* S, BiTree x);
/*出栈*/
bool Pop(SqStack* S, BiTree *x);
void CreateBiTree1(BiTree* T);
/*二叉树的遍历递归算法*/
/*先序遍历*/
void PreOrder(BiTree T);
/*中序遍历*/
void InOrder(BiTree T);
/*后序遍历*/
void PostOrder(BiTree T);
/*输出树结点*/
void visit(BiTree T);
/*二叉树的遍历非递归算法*/
/*先序遍历*/
void PreOrder2(BiTree T);
/*中序遍历*/
void InOrder2(BiTree T);
/*后序遍历*/
/*利用标志*/
void PostOrder3(BiTree T);
int main(void)
{
BiTree T = NULL;
printf("请输入以下字符串创建二叉树!!!\n");
printf("ABD##EG###C#F##\n");
CreateBiTree1(&T);
while (1)
{
int choice = TestMeanu();
switch (choice)
{
case 0:
exit(0);
break;
case 1:
printf("1、先序遍历\n");
printf("2、中序遍历\n");
printf("3、后序遍历\n");
printf("请输入要遍历的方式:");
int choice1;
scanf("%d", &choice1);
color(11);
switch (choice1)
{
case 1:
PreOrder(T);
break;
case 2:
InOrder(T);
break;
case 3:
PostOrder(T);
break;
default:
printf("输入不规范,请规范输入!!!!\n");
}
break;
case 2:
printf("1、先序遍历\n");
printf("2、中序遍历\n");
printf("3、后序遍历\n");
printf("请输入要遍历的方式:");
int choice2;
scanf("%d", &choice2);
color(11);
switch (choice2)
{
case 1:
PreOrder2(T);
break;
case 2:
InOrder2(T);
break;
case 3:
PostOrder3(T);
break;
default:
printf("输入不规范,请规范输入!!!!\n");
}
}
}
return 0;
}
void CreateBiTree1(BiTree* T)
{
Elemtype ch;
scanf("%c", &ch);
if (ch == '#')
*T = NULL;
else
{
*T = (BiTree)malloc(sizeof(BiTNode));
if (*T == NULL)
exit(false);
(*T)->data = ch;
(*T)->lchild = (*T)->rchild = NULL;
CreateBiTree1(&( (*T)->lchild )); //构建左子树
CreateBiTree1(&( (*T)->rchild)); //构建右子树
}
}
/*设置字体颜色*/
void color(short x)
{
/*
颜色函数SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),前景色 | 背景色 | 前景加强 | 背景加强);
前景色:数字0-15 或 FOREGROUND_XXX 表示 (其中XXX可用BLUE、RED、GREEN表示)
前景加强:数字8 或 FOREGROUND_INTENSITY 表示
背景色:数字16 32 64 或 BACKGROUND_XXX 三种颜色表示
背景加强: 数字128 或 BACKGROUND_INTENSITY 表示
主要应用:改变指定区域字体与背景的颜色
前景颜色对应值:
0=黑色 8=灰色
1=蓝色 9=淡蓝色 十六进制
2=绿色 10=淡绿色 0xa
3=湖蓝色 11=淡浅绿色 0xb
4=红色 12=淡红色 0xc
5=紫色 13=淡紫色 0xd
6=黄色 14=淡黄色 0xe
7=白色 15=亮白色 0xf
也可以把这些值设置成常量。
*/
if (x >= 0 && x <= 15)//参数在0-15的范围颜色
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x); //只有一个参数,改变字体颜色
else//默认的颜色白色
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
}
int TestMeanu(void)
{
color(16);
int choice;
printf("欢迎使用二叉树三种遍历算法测试程序!!!!!\n");
printf("0、退出测试程序\n");
printf("1、二叉树的递归遍历算法\n");
printf("2、二叉树的非递归遍历算法\n");
printf("请输入你需要测试的功能:");
scanf("%d", &choice);
return choice;
}
void InitStack(SqStack* S)
{
S->top = -1;
}
bool IsEmpty(SqStack S)
{
if (S.top == -1)
return true;
else
return false;
}
bool Push(SqStack* S, BiTree x)
{
if (S->top == Maxsize - 1)
return false;
S->data[++(S->top)] = x;
return true;
}
bool Pop(SqStack* S, BiTree* x)
{
if (S->top == -1)
return false;
*x = S->data[(S->top)--];
return true;
}
/*二叉树遍历的递归算法*/
/*先序遍历*/
void PreOrder(BiTree T)
{
if (T != NULL)
{
visit(T);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
/*中序遍历*/
void InOrder(BiTree T)
{
if (T != NULL)
{
InOrder(T->lchild);
visit(T);
InOrder(T->rchild);
}
}
/*后序遍历*/
void PostOrder(BiTree T)
{
if (T != NULL)
{
PostOrder(T->lchild);
PostOrder(T->rchild);
visit(T);
}
}
/*输出树结点*/
void visit(BiTree T)
{
printf("树结点的值:%c\n", T->data);
}
/*二叉树的非递归算法*/
/*先序遍历*/
void PreOrder2(BiTree T)
{
SqStack S;
InitStack(&S);
BiTree p = T;
while (p || !IsEmpty(S))
{
if (p)
{
visit(p);
Push(&S, p);
p = p->lchild;
}
else
{
Pop(&S, &p);
p = p->rchild;
}
}
}
/*中序遍历*/
void InOrder2(BiTree T)
{
SqStack S;
InitStack(&S);
BiTree p = T;
while (p || !IsEmpty(S))
{
if (p)
{
Push(&S, p);
p = p->lchild;
}
else
{
Pop(&S, &p);
visit(p);
p = p->rchild;
}
}
}
/*利用标志*/
struct stack
{
BiTree t;
int tag; // 标志
};
void PostOrder3(BiTree T)
{
struct stack s[Maxsize];
int top = -1;
while (T != NULL || top >= 0)
{
while (T != NULL)
{
s[++top].t = T;
s[top].tag = 0;
T = T->lchild; // 沿左分支向下
}
while (top != -1 && s[top].tag == 1)
visit(s[top--].t); // 退栈
if (top != -1)
{
s[top].tag = 1; // 标志访问过右子树被访问
T = s[top].t->rchild; // 沿右分支向下遍历
}
}
}
#define _CRT_SECURE_NO_WARNINGS
/*引入头文件*/
#include //引入头文件
#include
using namespace std;
#define Maxsize 100
typedef char Elemtype;
typedef struct BiTNode /*定义二叉树链式存储结构*/
{
Elemtype data;
struct BiTNode* lchild, * rchild;
}BiTNode, * BiTree;
typedef struct Stack /*定义堆栈存储结构*/
{
BiTree data[Maxsize];
int top;
}SqStack;
/*设置字体颜色*/
void color(short x);
/*测试菜单*/
int TestMeanu(void);
/*初始化堆栈*/
void InitStack(SqStack &S);
/*判断栈空*/
bool IsEmpty(SqStack S);
/*入栈*/
bool Push(SqStack &S, BiTree x);
/*出栈*/
bool Pop(SqStack &S, BiTree &x);
void CreateBiTree1(BiTree &T);
/*二叉树的遍历递归算法*/
/*先序遍历*/
void PreOrder(BiTree T);
/*中序遍历*/
void InOrder(BiTree T);
/*后序遍历*/
void PostOrder(BiTree T);
/*输出树结点*/
void visit(BiTree T);
/*二叉树的遍历非递归算法*/
/*先序遍历*/
void PreOrder2(BiTree T);
/*中序遍历*/
void InOrder2(BiTree T);
/*后序遍历*/
/*利用标志*/
void PostOrder3(BiTree T);
int main(void)
{
BiTree T = NULL;
printf("请输入以下字符串创建二叉树!!!\n");
printf("ABD##EG###C#F##\n");
CreateBiTree1(T);
while (1)
{
int choice = TestMeanu();
switch (choice)
{
case 0:
exit(0);
break;
case 1:
printf("1、先序遍历\n");
printf("2、中序遍历\n");
printf("3、后序遍历\n");
printf("请输入要遍历的方式:");
int choice1;
scanf("%d", &choice1);
color(11);
switch (choice1)
{
case 1:
PreOrder(T);
break;
case 2:
InOrder(T);
break;
case 3:
PostOrder(T);
break;
default:
printf("输入不规范,请规范输入!!!!\n");
}
break;
case 2:
printf("1、先序遍历\n");
printf("2、中序遍历\n");
printf("3、后序遍历\n");
printf("请输入要遍历的方式:");
int choice2;
scanf("%d", &choice2);
color(11);
switch (choice2)
{
case 1:
PreOrder2(T);
break;
case 2:
InOrder2(T);
break;
case 3:
PostOrder3(T);
break;
default:
printf("输入不规范,请规范输入!!!!\n");
}
}
}
return 0;
}
void CreateBiTree1(BiTree &T)
{
Elemtype ch;
scanf("%c", &ch);
if (ch == '#')
T = NULL;
else
{
T = (BiTree)malloc(sizeof(BiTNode));
if (T == NULL)
exit(false);
T->data = ch;
T->lchild = T->rchild = NULL;
CreateBiTree1(T->lchild); //构建左子树
CreateBiTree1(T->rchild); //构建右子树
}
}
/*设置字体颜色*/
void color(short x)
{
/*
颜色函数SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),前景色 | 背景色 | 前景加强 | 背景加强);
前景色:数字0-15 或 FOREGROUND_XXX 表示 (其中XXX可用BLUE、RED、GREEN表示)
前景加强:数字8 或 FOREGROUND_INTENSITY 表示
背景色:数字16 32 64 或 BACKGROUND_XXX 三种颜色表示
背景加强: 数字128 或 BACKGROUND_INTENSITY 表示
主要应用:改变指定区域字体与背景的颜色
前景颜色对应值:
0=黑色 8=灰色
1=蓝色 9=淡蓝色 十六进制
2=绿色 10=淡绿色 0xa
3=湖蓝色 11=淡浅绿色 0xb
4=红色 12=淡红色 0xc
5=紫色 13=淡紫色 0xd
6=黄色 14=淡黄色 0xe
7=白色 15=亮白色 0xf
也可以把这些值设置成常量。
*/
if (x >= 0 && x <= 15)//参数在0-15的范围颜色
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x); //只有一个参数,改变字体颜色
else//默认的颜色白色
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
}
int TestMeanu(void)
{
color(16);
int choice;
printf("欢迎使用二叉树三种遍历算法测试程序!!!!!\n");
printf("0、退出测试程序\n");
printf("1、二叉树的递归遍历算法\n");
printf("2、二叉树的非递归遍历算法\n");
printf("请输入你需要测试的功能:");
scanf("%d", &choice);
return choice;
}
void InitStack(SqStack &S)
{
S.top = -1;
}
bool IsEmpty(SqStack S)
{
if (S.top == -1)
return true;
else
return false;
}
bool Push(SqStack &S, BiTree x)
{
if (S.top == Maxsize - 1)
return false;
S.data[++S.top] = x;
return true;
}
bool Pop(SqStack &S, BiTree &x)
{
if (S.top == -1)
return false;
x = S.data[S.top--];
return true;
}
/*二叉树遍历的递归算法*/
/*先序遍历*/
void PreOrder(BiTree T)
{
if (T != NULL)
{
visit(T);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
/*中序遍历*/
void InOrder(BiTree T)
{
if (T != NULL)
{
InOrder(T->lchild);
visit(T);
InOrder(T->rchild);
}
}
/*后序遍历*/
void PostOrder(BiTree T)
{
if (T != NULL)
{
PostOrder(T->lchild);
PostOrder(T->rchild);
visit(T);
}
}
/*输出树结点*/
void visit(BiTree T)
{
printf("树结点的值:%c\n", T->data);
}
/*二叉树的非递归算法*/
/*先序遍历*/
void PreOrder2(BiTree T)
{
SqStack S;
InitStack(S);
BiTree p = T;
while (p || !IsEmpty(S))
{
if (p)
{
visit(p);
Push(S, p);
p = p->lchild;
}
else
{
Pop(S, p);
p = p->rchild;
}
}
}
/*中序遍历*/
void InOrder2(BiTree T)
{
SqStack S;
InitStack(S);
BiTree p = T;
while (p || !IsEmpty(S))
{
if (p)
{
Push(S, p);
p = p->lchild;
}
else
{
Pop(S, p);
visit(p);
p = p->rchild;
}
}
}
/*利用标志*/
struct stack
{
BiTree t;
int tag; // 标志
};
void PostOrder3(BiTree T)
{
struct stack s[Maxsize];
int top = -1;
while (T != NULL || top >= 0)
{
while (T != NULL)
{
s[++top].t = T;
s[top].tag = 0;
T = T->lchild; // 沿左分支向下
}
while (top != -1 && s[top].tag == 1)
visit(s[top--].t); // 退栈
if (top != -1)
{
s[top].tag = 1; // 标志访问过右子树被访问
T = s[top].t->rchild; // 沿右分支向下遍历
}
}
}