分析主要分析二叉树的非递归遍历,基于栈顺序存储二叉树的节点。
1 实现思路(具体的分析过程会在以下函数实现部分分析,中序遍历如下)
- 将树的所有节点标志位置为假(0),并将根节点压入栈中
- 进入循环,只要栈中元素个数大于0,进行循环操作
- 弹出栈顶元素
- 如果栈顶元素标志为真,直接输出,进行下次循环即可
- 如果栈顶元素标志为假,将标志改为真,并将栈顶节点的右子树、根、左子树压入栈中,再执行下次循环。
2 创建树节点
typedef struct Tree //二叉树
{
void *data; //数据域,void* 可保存任意数据类型的地址
struct Tree *left; //左子节点指针
struct Tree *right; //右子节点指针
int flag; //标志位
} Tree;
Tree *createTreeNode(void *data)
{
Tree *node = (Tree *)malloc(sizeof(Tree));
node->data = data;
node->left = NULL;
node->right = NULL;
node->flag = 0; //每个tree节点标志位默认为0
}
3 构建顺序存储的栈
#define SIZE 666
typedef struct Stack //构建顺序存储的栈
{
Tree *data[SIZE]; //栈的数据域,data数组的存储类型为Tree*,即二叉树节点地址
int size; //栈的大小
} Stack;
4 基于栈的顺序存储与先进后出原则,非递归实现二叉树的中序遍历
typedef struct Student //后续以二叉树节点保存Student数据信息为例
{
int age;
char name[20];
} Student;
void inOrderList(Tree *root)
{
if (root == NULL)
return;
Stack *stack = (Stack *)malloc(sizeof(Stack)); //向堆区申请内存
memset(stack->data, 0, sizeof(Tree *) * SIZE);//初始化
stack->size = 0;
stack->data[stack->size++] = root;//根节点入栈
while (stack->size > 0) //栈空间>0即执行循环
{
Tree *topTreeNode = stack->data[stack->size - 1];
stack->data[stack->size - 1] = NULL;//栈顶元素出栈
stack->size--;//栈大小-1
if (topTreeNode->flag) //如果节点标志位为1,直接输出
{
Student *stu = (Student *)topTreeNode->data;
printf("{id:%d,name:%s}\t", stu->age, stu->name);
continue;
}
topTreeNode->flag = 1;
if (topTreeNode->right)//右节点不为空时入栈,且size+1
stack->data[stack->size++] = topTreeNode->right;
stack->data[stack->size++] = topTreeNode;//根节点不为空时入栈,且size+1
if (topTreeNode->left) //左节点不为空时入栈,且size+1
stack->data[stack->size++] = topTreeNode->left;
}
free(stack);
stack = NULL;
}
5 函数测试与结果分析
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
Student stu[7] = {
{1, "jakes1"},
{2, "jakes2"},
{3, "jakes3"},
{4, "jakes4"},
{5, "jakes5"},
{6, "jakes6"},
{7, "jakes7"},
};
Tree *root = (Tree *)malloc(sizeof(Tree));
root->data = &stu[0];
root->flag = 0;
root->left = createTreeNode(&stu[1]);
root->right = createTreeNode(&stu[2]);
root->left->left = createTreeNode(&stu[3]);
root->left->left->right = createTreeNode(&stu[6]);
root->right->left = createTreeNode(&stu[4]);
root->right->right = createTreeNode(&stu[5]);//完成一棵树的构建
printf("中序遍历:");
inOrderList(root);
return 0;
}
main函数里面,构建的树如下(同前文的树结构)
非递归中序遍历的结果如下
由inOrderList函数,可知执行过程如下(为简化,stu0.flag=0表示stu0构造的tree节点的标志位为0;printf(stu0)表示输出stu的信息)。相比较递归遍历,此方法十分容易理解。
(放大图如下)
点击关注不迷路