上一篇文章介绍的是二叉树中有关递归的一些运算,这一篇主要介绍二叉树中非递归遍历的实现。主要引入了堆栈和队列的思想。
其中层次遍历运用了队列的思想,非递归的中序、先序和后序遍历皆借助了栈的思想。
层次遍历:
#include<stdio.h>
#include<stdlib.h>
#define Max 50
typedef struct BiTNode //二叉树结点结构体
{
char element; //数据域
struct BiTNode* lchild, * rchild; //指针域
}BiTNode, * BiTree; //定义一个指向struct BiTNode的指针
typedef struct QueueList {
BiTNode val[Max];
int front, rear;
}QueueList;
QueueList Q;
//队列初始化
void InitQueue(QueueList &Q) {
Q.front = Q.rear = 0;
}
//判断是否队满
bool IsEmpty(QueueList Q) {
if ((Q.rear + 1) % Max == Q.front)
return true;
return false;
}
//进队操作
bool EnQueue(QueueList& Q,BiTNode x) {
if (IsEmpty(Q))
return false;
Q.val[Q.rear]= x;
Q.rear = (Q.rear + 1) % Max;
return true;
}
void visit(BiTNode W) {
printf("%c", W.element);
}
//出队操作
bool DeQueue(QueueList& Q,BiTNode &p) {
//判断是否为空
if (Q.front == Q.rear)
return false;
visit( Q.val[Q.front]);
Q.front = (Q.front + 1) % Max;
p = Q.val[Q.front];
return true;
}
//先序构建二叉树(这里没有循环语句强调输入元素,但是函数为递归函数,结束的条件是输入的所有值为叶子结点)
void CreateBiTree(BiTree& T)
{
char ch;
ch = getchar();
if (ch == '#') //#代表空指针
T = NULL;
else
{
T = (BiTNode*)malloc(sizeof(BiTNode));
T->element = ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
//层次遍历输出二叉树
void LevelOrder(BiTree& T) {
InitQueue(Q);
BiTNode *p=T;
EnQueue(Q, *p);
while (!IsEmpty(Q)) {
if (p->lchild != NULL) {
EnQueue(Q, *p->lchild);
}
if (p->rchild != NULL)
EnQueue(Q, *p->rchild);
DeQueue(Q, *p);
if (Q.front==Q.rear)
break;
}
}
//先序输出二叉树(也是递归函数,结束的条件是输出最后一个结点)
void Clear(BiTree t) //清空二叉树
{
if (!t)
return;
Clear(t->lchild);
Clear(t->rchild);
free(t);
}
void main() {
BiTree T = NULL; //创建了一指针
printf("创建先序构建的二叉树:\n");
CreateBiTree(T);
printf("\n层次遍历遍历的结果为:");
LevelOrder(T);
}
非递归中序遍历:
void InOrder2(BiTree T)
{
InitStack(S); //初始化栈
BiTNode* p = T;
BiTNode* q = T;
while (p || !IsEmpty(S)) //S不空,p存在
{
if (p!=NULL) {
Push(S, *p);
p = p->lchild;
}
else {
visit(S.val[S.top]); //读取栈顶元素
*q=Pop(S); //以q来充当中间物,否则,*p=Pop(S)会报错,因为这里的p不指向任何值
S.top--;
p = q->rchild;
}
}
}
举个完整的例子瞅瞅:
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 50
//定义二叉树的结构体
typedef struct BiTNode
{
char data;
struct BiTNode* lchild, * rchild;
}BiTNode, * BiTree;
//定义栈的结构体
typedef struct SqStack
{
BiTNode val[MaxSize];
int top;
}SqStack;
SqStack S;
//初始化栈
void InitStack(SqStack& S)
{
S.top = -1;
}
//判断栈是否为空
bool IsEmpty(SqStack& S)
{
if (S.top == -1)
return true;
else
return false;
}
//进栈
bool Push(SqStack& S, BiTNode& T)
{
if (S.top == MaxSize - 1)
return false;
else
S.val[++S.top] = T;
return true;
}
void visit(BiTNode W) {
printf("%c", W.data);
}
//出栈
BiTNode Pop(SqStack S)
{
return S.val[S.top];
}
//非递归中序遍历
void InOrder2(BiTree T)
{
InitStack(S); //初始化栈
BiTNode* p = T;
BiTNode* q = T;
while (p || !IsEmpty(S)) //S不空,p存在
{
if (p!=NULL) {
Push(S, *p);
p = p->lchild;
}
else {
visit(S.val[S.top]); //读取栈顶元素
*q=Pop(S); //以q来充当中间物,否则,*p=Pop(S)会报错,因为这里的p不指向任何值
S.top--;
p = q->rchild;
}
}
}
//先序创建二叉树
void CreateBiTree(BiTree& T)
{
char ch;
ch = getchar();
if (ch == '#') //#代表空指针
T = NULL;
else
{
T = (BiTNode*)malloc(sizeof(BiTNode));
if (T) {
T->data = ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
}
int main() {
BiTree T; //创建了一指针
printf("创建先序构建的二叉树:\n");
CreateBiTree(T);
printf("\n中序遍历的结果为:");
InOrder2(T);
return 0;
}
非递归先序遍历:
//非递归先序遍历
void PreOrder2(BiTree T)
{
InitStack(S);
BiTNode *p = T;
BiTNode* q = T;
while (p || !IsEmpty(S))
{
if (p!=NULL) {
Push(S, *p); //入栈
visit(*p);
p = p->lchild;
}
else {
*q=Pop(S); //返回栈顶元素
S.top--; //消去栈顶元素
if (q) {
p = q->rchild;
}
}
}
}