二叉树的非递归遍历
一、概念
基础概念:二叉树的非递归遍历是通过栈来实现的,通过使用栈保存节点信息,实现非递归的遍历二叉树。
二、代码及过程
/**
*
*二叉树非递归实现
*
***/
#define maxSize 100
#define increment 50
#include<stdio.h>
#include<stdlib.h>
// 二叉树的定义
typedef struct treeNode{
char val;
struct treeNode *left,*right;
}treeNode,*tree;
// 栈的定义
typedef struct stack{
tree *base,*top;
int nowSize;
}stack;
// 队列的定义
typedef struct queue{
tree *base,*front,*rear;
}queue;
/******************* 二叉树 函数声明 ********************/
void createTree(tree &T); // 创建二叉树
void perOrder(tree T); // 先序遍历二叉树
void inOrder(tree T); // 中序遍历二叉树
void postOrder(tree T); // 后序遍历二叉树
void levelOrder(tree T); // 层次遍历二叉树
/******************* 二叉树 函数声明 ********************/
/******************* 栈 函数声明 ********************/
void initStack(stack &s); // 初始化栈
void push(stack &s,tree T); // 入栈
void pop(stack &s,tree &T); // 出栈
int ifStack(stack s); // 判断是否为空栈,为空返回1,不空返回0
void getTopElement(stack s,tree &T);// 获取栈顶元素
/******************* 栈 函数声明 ********************/
/******************* 队列 函数声明 ********************/
void initQueue(queue &q); // 初始化队列
void enQueue(queue &q,tree T); // 入队
void outQueue(queue &q,tree &T); // 出队
int ifQueue(queue q); // 判断是否为空队列,为空返回1,不空返回0
/******************* 队列 函数声明 ********************/
void main(){
// 创建二叉树
tree T;
createTree(T);
// 非递归先序遍历二叉树
printf("\n非递归先序遍历二叉树:\n");
perOrder(T);
// 非递归中序遍历二叉树
printf("\n非递归中序遍历二叉树:\n");
inOrder(T);
// 非递归后序遍历二叉树
printf("\n非递归后序遍历二叉树:\n");
postOrder(T);
// 非递归层次遍历二叉树
printf("\n非递归层次遍历二叉树:\n");
levelOrder(T);
printf("\n");
}
/******************* 二叉树 函数实现 ********************/
// 创建二叉树
void createTree(tree &T){
char data;
printf("请按先序创建二叉树(*表示空节点):");
scanf("%s",&data);
// 当前为空节点
if(data == '*'){
T = NULL;
}else{
// 不为空节点,递归创建二叉树
T = (treeNode *)malloc(sizeof(treeNode));
T->val = data;
createTree(T->left);
createTree(T->right);
}
}
// 先序遍历二叉树
void perOrder(tree T){
stack s;
initStack(s);
tree temp = T;
while(temp != NULL || ifStack(s) != 1){
if(temp != NULL){
printf("%3c",temp->val);
push(s,temp);
temp = temp->left;
}else{
pop(s,temp);
temp = temp->right;
}
}
}
// 中序遍历二叉树
void inOrder(tree T){
stack s;
initStack(s);
tree temp = T;
while(temp != NULL || ifStack(s) != 1){
if(temp != NULL){
push(s,temp);
temp = temp->left;
}else{
pop(s,temp);
printf("%3c",temp->val);
temp = temp->right;
}
}
}
// 后序遍历二叉树
void postOrder(tree T){
stack s;
initStack(s);
tree temp = T,pre = NULL;
push(s,temp); // 将根节点入栈
while(ifStack(s) != 1){
getTopElement(s,temp); // 获取栈顶元素
if(temp->left == NULL && temp->right == NULL || (pre != NULL &&(pre == temp->left || pre == temp->right))){
// 左右孩子都为空 或者 左右孩子已经输出(pre指针指向左孩子or右孩子,代表已经输出)。 则输出根节点
printf("%3c",temp->val);
pop(s,temp);
pre = temp;
}else{
if(temp->right != NULL){
push(s,temp->right);
}
if(temp->left != NULL){
push(s,temp->left);
}
}
}
}
// 层次遍历二叉树
void levelOrder(tree T){
queue q;
initQueue(q);
tree temp = T;
enQueue(q,temp); // 根节点入队
while(ifQueue(q) != 1){
outQueue(q,temp);
printf("%3c",temp->val);
if(temp->left != NULL){
enQueue(q,temp->left);
}
if(temp->right != NULL){
enQueue(q,temp->right);
}
}
}
/******************* 二叉树 函数实现 ********************/
/******************* 栈 函数实现 ********************/
// 初始化栈
void initStack(stack &s){
s.base = (tree *)malloc(maxSize * sizeof(tree));
if(!s.base){
printf("栈空间分配失败!");
return;
}
s.top = s.base;
s.nowSize = maxSize;
}
// 入栈
void push(stack &s,tree T){
// 判断当前栈空间是否已满
if(s.top - s.base >= s.nowSize){
s.base = (tree *)realloc(s.base,(s.nowSize + increment)*sizeof(tree));
if(!s.base){
printf("栈增量空间分配失败!");
return;
}
s.nowSize += increment;
s.top = s.base + s.nowSize;
}
*s.top++ = T;
}
// 出栈
void pop(stack &s,tree &T){
if(s.top == s.base){
printf("当前为空栈!");
return;
}
T = *(--s.top);
}
// 判断是否为空栈,为空返回1,不空返回0
int ifStack(stack s){
if(s.top == s.base){
return 1;
}
return 0;
}
// 获取栈顶元素
void getTopElement(stack s,tree &T){
if(s.top == s.base){
printf("当前为空栈!");
return;
}
T = *(s.top-1);
}
/******************* 栈 函数实现 ********************/
/******************* 队列 函数实现 ********************/
// 初始化队列
void initQueue(queue &q){
q.base = (tree *)malloc(maxSize * sizeof(tree));
if(!q.base){
printf("队列内存空间分配失败!");
return;
}
q.front = q.rear = q.base;
}
// 入队
void enQueue(queue &q,tree T){
*q.rear++ = T;
}
// 出队
void outQueue(queue &q,tree &T){
if(q.rear == q.front){
printf("当前为空队列!");
return;
}
T = *q.front++;
}
// 判断是否为空队列,为空返回1,不空返回0
int ifQueue(queue q){
if(q.rear == q.front){
return 1;
}
return 0;
}
/******************* 队列 函数实现 ********************/