数据结构中,实现二叉树遍历的方式有两种,一种是递归遍历,另外一种是非递归遍历。
本文考虑非递归遍历的情况。
在非递归遍历的实现中,需要构造一个链式栈来暂存树中节点,具体实现代码如下:
// 二叉树的非递归实现
#include<stdio.h>
#include<stdlib.h>
typedef struct BNode {
char data;
struct BNode* pLchild;
struct BNode* pRchild;
}BNode, *BTree;
/*
利用非递归实现二叉树遍历,需要用到栈的知识
*/
// 定义栈的表示方法
typedef struct Node {
BTree data;
struct Node* pNext;
}Node, *PNODE;
typedef struct Stack {
PNODE pTop;// 栈顶指针
PNODE PBottom;
}STACK, *PSTACK;
// 创建空栈函数
PSTACK create_stack();
// 入栈函数
void push_stack(PSTACK, BTree);
// 遍历栈
void traverse_stack(PSTACK);
// 出栈函数
bool pop_stack(PSTACK, BTree*);
// 判断栈空函数
bool is_empty(PSTACK);
// 清空栈
void clear_stack(PSTACK);
// 取栈顶元素
BTree getTop(PSTACK);
// --------------------------------------
//创建一棵二叉树
BTree create_tree();
//非递归实现二叉树的前序遍历
void pre_traverse(BTree);
//非递归实现二叉树的俄中序遍历
void in_traverse(BTree);
//非递归实现二叉树的后序遍历
void beh_traverse(BTree);
// 栈的操作
PSTACK create_stack() {
PSTACK pS = (PSTACK)malloc(sizeof(STACK));
//创建空节点
pS->pTop = (PNODE)malloc(sizeof(PNODE));
if (!pS || pS->pTop == NULL) {
printf("malloc failed");
exit(-1);
}
else {
pS->PBottom = pS->pTop;
pS->PBottom->pNext = NULL;
}
return pS;
}
bool is_empty(PSTACK pS) {
if (pS->pTop == pS->PBottom) {
return true;
}
else {
return false;
}
}
// 向pS指针指向的栈中添加数据val
void push_stack(PSTACK pS, BTree val) {
PNODE PNew = (PNODE)malloc(sizeof(Node));
if (PNew == NULL) {
printf("malloc failed");
exit(-1);
}
else {
PNew->data = val; //将树中的数据添加在栈中
PNew->pNext = pS->pTop;
pS->pTop = PNew;
}
return;
}
// 从栈中弹出数据,
bool pop_stack(PSTACK pS, BTree* pData) {
if (pS->pTop == pS->PBottom) {
return false;
}else {
PNODE p = pS->pTop;
*pData = p->data;
pS->pTop = p->pNext;
free(p);
p = NULL;
return true;
}
}
//遍历栈
void traverse_stack(PSTACK pS) {
PNODE pCurrent = pS->pTop;
while (pCurrent != pS->PBottom) {
printf("%d ", pCurrent->data);
pCurrent = pCurrent->pNext;
}
printf("\n");
return;
}
// 清空栈
void clear_stack(PSTACK pS) {
if (pS->pTop == pS->PBottom) {
return;
}else {
PNODE p = pS->pTop;
PNODE r = NULL;
while (p != pS->PBottom)
{
r = p->pNext; //先将下一个元素指针存储
free(p);
p = r;
}
pS->pTop == pS->PBottom;
}
}
// 返回栈顶元素
BTree getTop(PSTACK pS) {
if (!(pS->PBottom == pS->pTop)) {
return pS->pTop->data;
}
else {
return NULL;
}
}
// 创建一棵树
BTree create_tree() {
BTree pA = (BTree)malloc(sizeof(BNode));
BTree pB = (BTree)malloc(sizeof(BNode));
BTree pD = (BTree)malloc(sizeof(BNode));
BTree pE = (BTree)malloc(sizeof(BNode));
BTree pC = (BTree)malloc(sizeof(BNode));
BTree pF = (BTree)malloc(sizeof(BNode));
pA->data = 'A';
pB->data = 'B';
pD->data = 'D';
pE->data = 'E';
pC->data = 'C';
pF->data = 'F';
pA->pLchild = pB;
pA->pRchild = pC;
pB->pLchild = pD;
pB->pRchild = pE;
pD->pLchild = pD->pRchild = NULL;
pE->pLchild = pE->pRchild = NULL;
pC->pLchild = pF;
pC->pRchild = NULL;
pF->pLchild = pF->pRchild = NULL;
return pA;
}
// 树的前序遍历 非递归实现
void pre_traverse(BTree pTree) {
PSTACK stack = create_stack();// 创建一个空栈
BTree node_pop; //保存出栈节点
BTree pCur = pTree;
// 直到当前节点pCur为空且栈为空,循环结束
while (pCur || !(stack->pTop == stack->PBottom)) {
//从根节点开始,输出当前节点,并将其入栈。
// 同时置其左孩子为当前节点,直到其没有左孩子,
printf("%c ", pCur->data);
push_stack(stack, pCur);
pCur = pCur->pLchild;
//如果当前节点pCur为NULL且栈不空,则将栈顶节点出栈,
//同时置其右孩子为当前节点,循环判断,直至pCur不为空
while (!pCur && !(stack->PBottom == stack->pTop))
{
pCur = getTop(stack);
pop_stack(stack, &node_pop);
pCur = pCur->pRchild;
}
}
}
int main() {
BTree pTree = create_tree();
printf("非递归实现前序遍历结果:");
pre_traverse(pTree);
printf("\n");
system("pause");
}