注意事项:
- 先序非递归算法的思想:1.二叉树指针不为空时,根指针入栈,指针指向左孩子,并将根结点输出。如果二叉树指针为空,根指针出栈,指针指向右孩子。(每一次出栈后指针指向其右孩子,可以保证每一个左右结点都可以遍历到)
- 后序遍历非递归算法:从根结点开始,将所有最左结点全部压栈,每当一个结点出栈时,都先扫描该结点的右子树,只有当一个结点的左孩子和右孩子结点均被访问过了,才能访问结点自身。
- 后序遍历算法的一个特性:就是当访问某个结点时,栈中所保存的元素,正好是这个结点的所有祖先。根据这个特性,就很容易解决下面如下问题:
(1).当给定一个叶子结点,要求输出该叶子结点的所有祖先
(2).输出根结点到所有叶子结点的路径
(3).如果二叉树结点的值是数值,那么求每条路径上值之和,也可以利用二叉树后序遍历的非递归算法这个特性 - 半小时BUG:在定义链栈头指针的时候,没有将其初始化指向一处分配好的空间,导致了野指针。
#include<stdio.h>
#include<stdlib.h>
#define StackElement BiTree
typedef struct BiTNode
{
char data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
typedef struct LSNode
{
StackElement data;
struct LSNode * next;
}LSNode, *LinkStack;
void InitStack(LinkStack *s);
void Push(LinkStack s, StackElement i);
void Pop(LinkStack s, StackElement *i);
int StackEmpty(LinkStack s);
void CreatBiTree(BiTree *t);
void DestroyBiTree(BiTree *t);
void PreOrderTraverse(BiTree t);
void InOrderTraverse(BiTree t);
void PostOrderTraverse(BiTree t);
int main()
{
BiTree t = NULL;
CreatBiTree(&t);
printf("Non-recursive traversal is\n");
PreOrderTraverse(t);
InOrderTraverse(t);
PostOrderTraverse(t);
return 0;
}
void InitStack(LinkStack *s)
{
(*s)->next = NULL;
}
void Push(LinkStack s, StackElement i)
{
LinkStack p = (LinkStack)malloc(sizeof(LSNode));
p->data = i;
p->next = s->next;
s->next = p;
}
void Pop(LinkStack s, StackElement *i)
{
LinkStack p = s->next;
s->next = p->next;
(*i) = p->data;
free(p);
}
int StackEmpty(LinkStack s)
{
if (s->next)
return 0;
else
return 1;
}
void CreatBiTree(BiTree *t)
{
char ch;
scanf_s("%c", &ch);
if (ch == ' ')
*t = NULL;
else
{
*t = (BiTree)malloc(sizeof(BiTNode));
if (!*t)
exit(1);
(*t)->data = ch;
CreatBiTree(&((*t)->lchild));
CreatBiTree(&((*t)->rchild));
}
}
void DestroyBiTree(BiTree *t)
{
if (*t)
{
if ((*t)->lchild)
DestroyBiTree(&((*t)->lchild));
if ((*t)->rchild)
DestroyBiTree(&((*t)->rchild));
free(*t);
(*t) = NULL;
}
}
void PreOrderTraverse(BiTree t)
{
LinkStack s = (LinkStack)malloc(sizeof(LSNode));
InitStack(&s);
while (t || !StackEmpty(s))
{
if (t)
{
Push(s, t);
printf("%c->", t->data);
t = t->lchild;
}
else
{
Pop(s, &t);
t = t->rchild;
}
}
printf("NULL\n");
}
void InOrderTraverse(BiTree t)
{
LinkStack s = (LinkStack)malloc(sizeof(LSNode));
InitStack(&s);
while (t || !StackEmpty(s))
{
if (t)
{
Push(s, t);
t = t->lchild;
}
else
{
Pop(s, &t);
printf("%c->", t->data);
t = t->rchild;
}
}
printf("NULL\n");
}
while(T || !empty_Stack(S)){
if(T){
Push_Stack(S,T);
Push_Stack(CS,T);
T=T->right;
}else{
T=Pop_Stack(S)->data;
T=T->left;
}
}
while(CS->top!=NULL){
printf("%c",CS->top->data->element);
CS->top=CS->top->next;
}
while (T || !empty_Stack(S)) {
if (T) {
T->flag = 0;
Push_Stack(S, T);
T = T->left;
}
else {
T = Pop_Stack(S)->data;
if (T->flag == 0) {
T->flag = 1;
Push_Stack(S, T);
T = T->right;
}
else {
if (T->flag == 1) {
printf("%c", T->element);
T = NULL;
}
}
}
void PostOrderTraverse(BiTree t)
{
BiTree SqStack[100];
int top = -1;
int flag = 1;
BiTree p;
while (t != NULL || top > -1)
{
while (t != NULL)
{
top++;
SqStack[top] = t;
t = t->lchild;
}
flag = 1;
p = NULL;
while (top > -1 && flag == 1)
{
t = SqStack[top];
if (t->rchild == p || t->rchild == NULL)
{
top--;
printf("%c->", t->data);
p = t;
}
else
{
t = t->rchild;
flag = 0;
}
}
}
printf("NULL\n");
}