本文为前几章内容的扩展,后序遍历的循环形式
循环遍历较为复杂,建议使用递归完成
详细内容请看前文,本文作为扩展内容
#include<stdio.h>
#include<stdlib.h>
typedef char E;//数据类型
typedef struct TreeNode * Node;//二叉树结点指针
typedef struct StackNode * SNode; //栈结点指针
//二叉树结点
struct TreeNode
{
E element;
struct TreeNode * left;
struct TreeNode * right;
int flag; //需要经历左右子树都被遍历才行,这里用flag存一下状态,0表示左子树遍历完成,1表示右子树遍历完成
};
//栈结点
struct StackNode
{
Node element;//存进的二叉树结点
struct StackNode * next;
};
//栈函数区
//初始化栈
void initStack(SNode head)
{
head->next = NULL;
}
//入栈
int pushStack(SNode head, Node element)
{
SNode node = malloc(sizeof(struct StackNode));
if(node == NULL) return 0;
node->next = head->next;
node->element = element;
head->next = node;
return 1;
}
//判断栈是否为空
int isEmpty(SNode head)
{
if(head->next == NULL)
{
return 0;
}
else
{
return 1;
}
}
//出栈
Node popStack(SNode head)
{
SNode top = head->next;
head->next = head->next->next;
Node e = top->element;
free(top);
return e;
}
//新增操作
Node peekStack(SNode head)//获取栈顶存的二叉树结点(只获取值)
{
return head->next->element;
}
//二叉树函数区
//后序遍历(循环)
void postOrder(Node root)
{
struct StackNode stack;
initStack(&stack);
while (root || isEmpty(&stack))
{
while (root)
{
pushStack(&stack, root);
root->flag = 0;//左子树遍历完(无左子结点)入栈
root = root->left;
}
root = peekStack(&stack);//获取结点查看状态
if(root->flag == 0)//只遍历了左子树
{
root->flag = 1;//状态改变
root = root->right;//遍历右子树
}
else //左右子树都遍历过
{
printf("%c", root->element);//左右子树都遍历过打印
popStack(&stack);//将打印完的结点出栈
root = NULL;//设置为空指针结束循环然后从栈顶取结点
}
}
}
int main()
{
Node a = malloc(sizeof(struct TreeNode));
Node b = malloc(sizeof(struct TreeNode));
Node c = malloc(sizeof(struct TreeNode));
Node d = malloc(sizeof(struct TreeNode));
Node e = malloc(sizeof(struct TreeNode));
Node f = malloc(sizeof(struct TreeNode));
a->element='A';
b->element='B';
c->element='C';
d->element='D';
e->element='E';
f->element='F';
a->left=b;
a->right=c;
b->left=d;
b->right=e;
c->left=NULL;
c->right=f;
d->left=NULL;
d->right=NULL;
e->left=NULL;
e->right=NULL;
f->left=NULL;
f->right=NULL;
postOrder(a);
return 0;
}