各种遍历的非递归方法使用堆栈作为辅助,定义的头文件如下:
#define OK 1
#define ERROR -1
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef char TElemType; //二叉树数据类型
typedef struct BiTNode
{
TElemType data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree; //二叉树结点
typedef BiTree SElem; //堆栈中元素数据类型
typedef struct SNode
{
SElem e;
struct SNode *next;
}SNode; //堆栈链表结点
typedef struct
{
SNode *base, *top;
int size;
}Stack; //堆栈链表
Status InitStack(Stack &S); //初始化堆栈
Status StackEmpty(Stack S); //判断堆栈是否为空
Status Push(Stack &S, SElem e); //压栈
Status Pop(Stack &S, SElem &e); //出栈
Status CreateBiTree(BiTree &T); //先序构造二叉树
Status PreOrderTraverse(BiTree T, Status (*Visit)(TElemType e)); //先序遍历
Status InOrderTraverse(BiTree T, Status (*Visit)(TElemType e)); //中序遍历
Status PostOrderTraverse(BiTree T, Status (*Visit)(TElemType e)); //后序遍历
1.1先序遍历(非递归算法)
Status PreOrderTraverse(BiTree T, Status (*Visit)(TElemType e))
{
BiTree p;
Stack S;
InitStack(S);
p = T;
while(p || !StackEmpty(S))
{
if(p)
{
if(!Visit(p->data)) return ERROR;
Push(S, p->rchild);
p = p->lchild;
}
else
Pop(S, p);
}
return OK;
}
Status PreOrderTraverse(BiTree T, Status (*Visit)(TElemType e))
{
if(T)
{
if(Visit(T->data))
if(PreOrderTraverse(T->lchild, Visit))
if(PreOrderTraverse(T->rchild, Visit))
return OK;
return ERROR;
}
else
return ERROR;
}
2.1中序遍历(非递归算法)
Status InOrderTraverse(BiTree T, Status (*Visit)(TElemType e))
{
Stack S;
InitStack(S);
BiTNode *cur = T;
while(cur || !StackEmpty(S))
{
if(cur)
{
Push(S, cur);
cur = cur->lchild;
}
else
{
if(!StackEmpty(S))
{
Pop(S, cur);
if(!Visit(cur->data)) return ERROR;
cur = cur->rchild;
}
}
}
return OK;
}
2.2中序遍历(递归算法)
Status InOrderTraverse(BiTree T, Status (*Visit)(TElemType e))
{
if(T)
{
if(InOrderTraverse(T->lchild, Visit))
if(Visit(T->data))
if(InOrderTraverse(T->rchild, Visit))
return OK;
return ERROR;
}
else
return ERROR;
}
3.1后序遍历(非递归算法)
//要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,
//先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者
//右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上
//述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,
//左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
Status PostOrderTraverse(BiTree T, Status (*Visit)(TElemType e))
{
SElem elem;
BiTNode *cur = T;
BiTNode *pre = NULL;
Stack S;
InitStack(S);
Push(S, cur);
while(!StackEmpty(S))
{
cur = S.top->e; //取栈顶元素
if((cur->lchild == NULL && cur->rchild == NULL) ||
(pre != NULL && (pre == cur->lchild || pre == cur->rchild)))
{
Visit(cur->data);
Pop(S, elem);
pre = cur;
}
else
{
if(cur->rchild != NULL)
Push(S, cur->rchild);
if(cur->lchild != NULL)
Push(S, cur->lchild);
}
}
return OK;
}
3.2后序遍历(递归算法)
Status PostOrderTraverse(BiTree T, Status (*Visit)(TElemType e))
{
if(T)
{
if(PostOrderTraverse(T->lchild, Visit))
if(PostOrderTraverse(T->rchild, Visit))
if(!Visit(T->data))
return OK;
return ERROR;
}
else
return ERROR;
}