#include<iostream>
using namespace std;
typedef struct treeNode
{
char data;
struct treeNode*LChild;
struct treeNode*RChild;
}TREE,*LPTREE;
//别名中lp一般表示是指针别名
LPTREE createNode(char data)
{
LPTREE newNode=(LPTREE)malloc(sizeof(TREE));
newNode->data=data;
newNode->LChild=NULL;
newNode->RChild=NULL;
return newNode;
}
//没有规律的树
void insertNode(LPTREE parentNode,LPTREE LChild,LPTREE RChild)
{
parentNode->LChild=LChild;
parentNode->RChild=RChild;
}
//打印当前节点中的元素
void printCurNodeData(LPTREE curData)
{
cout<<curData->data;
}
//递归法:领悟
//先序:根 左 右
void preOrder(LPTREE root)
{
if(root!=NULL)
{
printCurNodeData(root); //根
preOrder(root->LChild); //左
preOrder(root->RChild); //右
}
}
//非递归:运用栈
void preOrderBystack(LPTREE root)
{
if(root==NULL)
{
return ;
}
//准备栈
LPTREE stack[10]; //存储每次打印节点的位置
int stackTop=-1; //栈顶标记
LPTREE pMove=root; //从根节点开始做打印
while(stackTop!=-1||pMove)
{
//根 左 右
//找到最左边
while(pMove)
{
//把路径入栈+打印走过的节点
cout<<pMove->data;
stack[++stackTop]=pMove;
pMove=pMove->LChild;
}
//无路可走的处理
if(stackTop!=-1)
{
pMove=stack[stackTop]; //获取栈顶元素
stackTop--; //出栈
pMove=pMove->RChild;
}
}
}
//中序: 左 根 右
void midOrder(LPTREE root)
{
if(root!=NULL)
{
midOrder(root->LChild); //左
printCurNodeData(root); //根
midOrder(root->RChild); //右
}
}
//非递归中序
void midOrderBystack(LPTREE root)
{
if(root==NULL)
{
return ;
}
//栈的准备工作
LPTREE stack[10];
int stackTop=-1;
//定义移动的指针
LPTREE pMove=root;
while(stackTop!=-1||pMove)
{
//走到最左边,把走过的结点入栈
while(pMove)
{
stack[++stackTop]=pMove;
pMove=pMove->LChild;
}
//出栈(需要打印数据)
if(stackTop!=-1)
{
pMove=stack[stackTop--];
cout<<pMove->data;
pMove=pMove->RChild;
}
}
}
//后序: 左 右 根
void lastOrder(LPTREE root)
{
if(root!=NULL)
{
lastOrder(root->LChild); //左
lastOrder(root->RChild); //右
printCurNodeData(root); //根
}
}
//非递归后序
void lastOrderBystack(LPTREE root)
{
if(root==NULL)
{
return ;
}
//栈的准备工作
LPTREE stack[10];
int stackTop=-1;
//定义移动的指针
LPTREE pMove=root;
LPTREE pLastVisit=NULL;//访问标记
//左 右 根
while(pMove)
{
stack[++stackTop]=pMove;
pMove=pMove->LChild;
}
while(stackTop!=-1)
{
pMove=stack[stackTop--];
if(pMove->RChild==NULL||pMove->RChild==pLastVisit)
{
//如果被访问就可以打印当前结点数据
cout<<pMove->data;
pLastVisit=pMove; //改变标记位置
}
else
{
//右边没有被访问
stack[++stackTop]=pMove;
pMove=pMove->RChild;
while(pMove)
{
stack[++stackTop]=pMove;
pMove=pMove->LChild;
}
}
}
}
int main()
{
//死板的创建过程,无实际作用
LPTREE A=createNode('A');
LPTREE B=createNode('B');
LPTREE C=createNode('C');
LPTREE D=createNode('D');
LPTREE E=createNode('E');
LPTREE F=createNode('F');
LPTREE G=createNode('G');
insertNode(A, B, C);
insertNode(B,D,NULL);
insertNode(D, NULL,G);
insertNode(C,E,F);
cout<<"先序遍历:"<<endl;
preOrder(A);
cout<<endl;
cout<<"先序遍历(非递归的方式)"<<endl;
preOrderBystack(A);
cout<<endl;
cout<<"中序遍历:"<<endl;
midOrder(A);
cout<<endl;
cout<<"中序遍历(非递归的方式)"<<endl;
midOrderBystack(A);
cout<<endl;
cout<<"后序遍历:"<<endl;
lastOrder(A);
cout<<endl;
cout<<"后序遍历(非递归的方式)"<<endl;
lastOrderBystack(A);
cout<<endl;
}