二叉树的非递归遍历:先序、中序、后续、层序。
其中前三种用了栈来辅助存储结点,层序利用了队列来辅助存储结点。
后序较前面两种遍历稍微复杂点,因为根结点是最后输出的,所有根结点要访问到2次,在第二次访问时输出,需要做辅助标记。
为了简化问题,二叉树也简单的形同:ABC##DE###FG### #代表空结点。
当然,为了和前面的知识点联系起来,stack和queue都是自己写的,没有用STL容器里的,当然换容器写的话就要简洁很多。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct BiTNode
{
char data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
typedef struct LNode
{
BiTree tree;
struct LNode *next;
int lenght;
}LNode, *Linklist, *Quept;
typedef struct LinkQue
{
Quept rear;
Quept front;
}LinkQue;
void InitStack(Linklist &s)
{
s = (LNode*)malloc(sizeof(LNode));
s->next = NULL;
s->lenght = 0;
}
void InitQueue(LinkQue &linkq)
{
linkq.rear = linkq.front = (Quept)malloc(sizeof(LNode));
linkq.front->next = NULL;
}
int EmptyQueue(LinkQue q)
{
if(q.front->next == NULL)
return 1;
else
return 0;
}
void CreatTree(BiTree &T)
{
char e;
e = getchar();
if(e == '#')
T = NULL;
else
{
T = (BiTNode *)malloc(sizeof(BiTNode));
T->data = e;
CreatTree(T->lchild);
CreatTree(T->rchild);
}
}
void Push(Linklist &s, BiTree T)
{
Linklist p;
p = (LNode*)malloc(sizeof(LNode));
p->tree = T;
p->next = s->next;
s->next = p;
s->lenght++;
}
int EmptyStack(Linklist s)
{
if(s->next != NULL)
return 0;
else
return 1;
}
BiTree GetTop(Linklist s)
{
BiTree t;
t = s->next->tree;
return t;
}
void Pop(Linklist &s)
{
Linklist p;
p = (LNode*)malloc(sizeof(LNode));
p = s->next;
s->next = p->next;
free(p);
s->lenght--;
}
void EnQueue(LinkQue &q, BiTree T)
{
Quept p;
p = (Quept)malloc(sizeof(LNode));
p->tree = T;
p->next = NULL;
q.rear->next = p;
q.rear = p;
}
BiTree DeQueue(LinkQue &q)
{
Quept p;
BiTree t;
p = q.front->next;
t = p->tree;
q.front->next = p->next;
if(q.rear==p) q.rear = q.front;
free(p);
return t;
}
void PreOrderTraverse(BiTree T)
{
Linklist s;
BiTree p;
p = T;
InitStack(s);
while(p || !EmptyStack(s))
{
if(p)
{
printf("%c", p->data);
Push(s, p);
p = p->lchild;
}
else
{
p = GetTop(s);
Pop(s);
p = p->rchild;
}
}
printf("\n");
}
void InOrderTraverse(BiTree T)
{
Linklist s;
InitStack(s);
BiTree p;
p = T;
while(p || !EmptyStack(s))
{
if(p)
{
Push(s, p);
p = p->lchild;
}
else
{
p = GetTop(s);
Pop(s);
printf("%c", p->data);
p = p->rchild;
}
}
printf("\n");
}
void PostOrderTraverse(BiTree T)
{
Linklist s;
InitStack(s);
BiTree p, q;
int mark[101]; //make sure the stack size is less than 100
memset(mark, 0, sizeof(int));
p = T;
while(p || !EmptyStack(s))
{
if(p) //from the root node to traverse left child find the left corner node
{
Push(s, p);
mark[s->lenght] = 0; //visit left tree node right tree node not visit set mark 0
p = p->lchild;
}
else //left tree node have traverse
{
if(mark[s->lenght] == 0) //right node not visit visit right node
{
mark[s->lenght] = 1;
p = GetTop(s);
p = p->rchild;
}
else
{
q = GetTop(s);
printf("%c", q->data);
Pop(s);
}
}
}
printf("\n");
}
void LevelOrderTraverse(BiTree T)
{
BiTree p;
LinkQue q;
InitQueue(q);
if(T)
{
EnQueue(q, T);
}
while(!EmptyQueue(q))
{
p = DeQueue(q);
printf("%c", p->data);
if(p->lchild) EnQueue(q, p->lchild);
if(p->rchild) EnQueue(q, p->rchild);
}
printf("\n");
}
int CountLeaves(BiTree T)
{
if(T == NULL)
return 0;
else
{
if(T->lchild==NULL && T->rchild==NULL) return 1;
return CountLeaves(T->lchild) + CountLeaves(T->rchild);
}
}
int CountDepth(BiTree T)
{
if(T==NULL)
return 0;
else
{
return (CountDepth(T->lchild)>CountDepth(T->rchild)?CountDepth(T->lchild):CountDepth(T->rchild)) + 1;
}
}
int main()
{
BiTree bitree;
int leaves, depth;
printf("Creating binary tree, e.g. ABC##DE###FG###, empty node use # .\n");
CreatTree(bitree);
printf("PreOrder traverse tree:\n");
PreOrderTraverse(bitree);
printf("InOrder traverse tree:\n");
InOrderTraverse(bitree);
printf("PostOrder traverse tree:\n");
PostOrderTraverse(bitree);
printf("LevelOrder traverse tree:\n");
LevelOrderTraverse(bitree);
leaves = CountLeaves(bitree);
printf("The tree leaves is %d.\n", leaves);
depth = CountDepth(bitree);
printf("The tree depth is %d.\n", depth);
return 0;
}