先序非递归
先序遍历的非递归过程为:
沿左子树深入时,入栈之前访问该结点,继续深入,为NULL时,则返回并弹出前面压入的节点,从该结点的右子树继续深入
如图所示:
代码实现:
void PreNotOrder(BTree root)
{
if (root == NULL)
exit(-1);
stack myStack;
StackInit(&myStack);//初始化栈
BTree pmove = root;
while (pmove != NULL || (!StackIsEmpty(&myStack)))//当根节点不为空且栈不满时
{
/*while (pmove != NULL)
{
printf("%c ", pmove->data);
PushStack(&myStack, pmove);
pmove = pmove->lchild;
}
if(!(StackIsEmpty(&myStack)))
{
pmove = GetStackTopValue(&myStack);
PopStack(&myStack);
pmove = pmove->rchild;
}*/
if (pmove != NULL)//深入左子树
{
printf("%c ", pmove->data);//访问该结点
PushStack(&myStack, pmove);//入栈
pmove = pmove->lchild;//深入当前结点的左子树
}
else
{
pmove = GetStackTopValue(&myStack);//取栈顶元素
PopStack(&myStack);//栈顶元素出栈
pmove = pmove->rchild;//深入右子树
}
}
}
中序非递归
而中序遍历的方法和先序遍历相似,只是访问结点的时机不同。
代码:
void InNotOrder(BTree root)
{
if (root == NULL)
exit(-1);
stack myStack;
StackInit(&myStack);
BTree temp = root;
while (temp != NULL || (!StackIsEmpty(&myStack)))
{
if (temp != NULL)
{
PushStack(&myStack, temp);
temp = temp->lchild;
}
else
{
temp = GetStackTopValue(&myStack);
printf("%c ", temp->data);
PopStack(&myStack);
temp = temp->rchild;
}
}
}
后序非递归
代码:
void PostNotOrder(BTree root)
{
if (root == NULL)
exit(-1);
stack myStack;
StackInit(&myStack);
BTree temp = root;
while (temp != NULL || (!StackIsEmpty(&myStack)))
{
if (temp != NULL)
{
PushStack(&myStack, temp);//入栈
myStack.flag[myStack.top] = 1;//记录第几次访问根节点
temp = temp->lchild;
}
else
{
if (myStack.flag[myStack.top] == 2)//第三次经过根节点时访问根节点并出栈
{
temp = GetStackTopValue(&myStack);
printf("%c ", temp->data);
PopStack(&myStack);
temp = NULL;
}
else//左子树访问完,访问右子树
{
temp = GetStackTopValue(&myStack);
myStack.flag[myStack.top] = 2;//第二次经过根节点
temp = temp->rchild;
}
}
}
}
完整代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
#include <Windows.h>
#define MAXSIZE 20
#define FLAG_MAXSIZE 30
typedef char DataType;
//二叉树结构体
typedef struct Tree
{
DataType data;
struct Tree* lchild, * rchild;
}Tree,*BTree;
//栈的结构体
typedef struct stack
{
BTree data[MAXSIZE];
int flag[FLAG_MAXSIZE];
int top;//栈顶指针
}stack;
//初始化栈
void StackInit(stack* myStack)
{
for (int i = 0; i < MAXSIZE; i++)
{
myStack->data[0];
}
for (int i = 0; i < FLAG_MAXSIZE; i++)
{
myStack->flag[i] = 0;
}
myStack->top = -1;
}
//入栈
void PushStack(stack* myStack, BTree data)
{
if (myStack->top == MAXSIZE)
{
printf("栈满不能入栈!\n");
exit(-1);
}
myStack->top++;
myStack->data[myStack->top] = data;
}
//判断栈是否为空
bool StackIsEmpty(stack* myStack)
{
if (myStack->top < 0)
return true;
else
return false;
}
//出栈
void PopStack(stack* myStack)
{
if (StackIsEmpty(myStack))
{
printf("栈已为空不能出栈!\n");
exit(-1);
}
//myStack->data[myStack->top] = NULL;
myStack->top--;
}
//取栈顶元素
BTree GetStackTopValue(stack* myStack)
{
if (StackIsEmpty(myStack))
{
printf("栈已为空不能出栈!\n");
exit(-1);
}
return myStack->data[myStack->top];
}
int flag = 0;
//创建二叉树
BTree CreateBTree()
{
BTree root=NULL;
DataType data;
char temp = 0;
if (flag == 0)
{
printf("请输入根节点:");
flag = 1;
}
scanf_s("%c", &data, 1);
temp = getchar();
if (data == '#')
{
return NULL;
}
else
{
(BTree)root = (BTree)malloc(sizeof(Tree));
if (root == NULL)
{
printf("分配内存失败!\n");
exit(-1);
}
root->data = data;
printf("请输入%c的左孩子:", root->data);
root->lchild = CreateBTree();
printf("请输入%c的右孩子:", root->data);
root->rchild = CreateBTree();
}
return root;
}
//先序非递归遍历
void PreNotOrder(BTree root)
{
if (root == NULL)
exit(-1);
stack myStack;
StackInit(&myStack);//初始化栈
BTree pmove = root;
while (pmove != NULL || (!StackIsEmpty(&myStack)))//当根节点不为空且栈不满时
{
/*while (pmove != NULL)
{
printf("%c ", pmove->data);
PushStack(&myStack, pmove);
pmove = pmove->lchild;
}
if(!(StackIsEmpty(&myStack)))
{
pmove = GetStackTopValue(&myStack);
PopStack(&myStack);
pmove = pmove->rchild;
}*/
if (pmove != NULL)//深入左子树
{
printf("%c ", pmove->data);//访问该结点
PushStack(&myStack, pmove);//入栈
pmove = pmove->lchild;//深入当前结点的左子树
}
else
{
pmove = GetStackTopValue(&myStack);//取栈顶元素
PopStack(&myStack);//栈顶元素出栈
pmove = pmove->rchild;//深入右子树
}
}
}
//二叉树中序非递归遍历
void InNotOrder(BTree root)
{
if (root == NULL)
exit(-1);
stack myStack;
StackInit(&myStack);
BTree temp = root;
while (temp != NULL || (!StackIsEmpty(&myStack)))
{
if (temp != NULL)
{
PushStack(&myStack, temp);
temp = temp->lchild;
}
else
{
temp = GetStackTopValue(&myStack);
printf("%c ", temp->data);
PopStack(&myStack);
temp = temp->rchild;
}
}
}
//二叉树后序非递归遍历
void PostNotOrder(BTree root)
{
if (root == NULL)
exit(-1);
stack myStack;
StackInit(&myStack);
BTree temp = root;
while (temp != NULL || (!StackIsEmpty(&myStack)))
{
if (temp != NULL)
{
PushStack(&myStack, temp);//入栈
myStack.flag[myStack.top] = 1;//记录第几次访问根节点
temp = temp->lchild;
}
else
{
if (myStack.flag[myStack.top] == 2)//第三次经过根节点时访问根节点并出栈
{
temp = GetStackTopValue(&myStack);
printf("%c ", temp->data);
PopStack(&myStack);
temp = NULL;
}
else//左子树访问完,访问右子树
{
temp = GetStackTopValue(&myStack);
myStack.flag[myStack.top] = 2;//第二次经过根节点
temp = temp->rchild;
}
}
}
}
void test_Tree1()
{
BTree root;
root = CreateBTree();
printf("先序非递归遍历的遍历序列为:");
PreNotOrder(root);
printf("\n");
printf("中序非递归遍历的遍历序列为:");
InNotOrder(root);
printf("\n");
printf("后序非递归遍历的遍历序列为:");
PostNotOrder(root);
printf("\n");
}
int main(void)
{
test_Tree1();
system("pause");
return EXIT_SUCCESS;
}