递归与非递归二叉树遍历
前段时间意外收到MS的电面,因为现在做的工作基本上是与音频、音乐信号处理相关,外带互联网全能打杂型。本质上跟计算机纯软件不是太相关。我最后选择了自己比较感兴趣的IMML组面试了一下。
面试基本上就是英语口语面试和二叉树相关的内容。所以想进微软的同学,这两项基本功要打好基础了。
笔试的第一题是用非递归的方法遍历二叉树,这个再学校的时候也没有复习到,只用过递归的方法,工作中也没有用到,所以一时半刻也没写准确,回去学习了一下,补习了一下,不过估计过段时间,还是会忘记,呵呵。
头文件
typedef struct BiNode
{
int value;
BiNode* pLeftChild;
BiNode* pRightChild;
int state;
};
typedef BiNode* BiTree;
void CreateBiTree1(BiNode **root);
void LayerPrint(BiNode *root);
void prePrint(BiNode* root);
void midPrint(BiNode* root);
void postPrint(BiNode* root);
void prePrint_nonRecusive(BiNode* root);
void midPrint_nonRecusive(BiNode* root);
void postPrint_nonRecusive(BiNode* root);
源文件
#include "CreateBiTree.h"
#include <malloc.h>
#include <stdio.h>
#include <stack>
#include <queue>
using namespace std;
void CreateBiTree1(BiNode **root)//递归形式,先序生成树
{
int input;
scanf("%d", &input);
if(input == -1)
{
return ;
}
*root = (BiNode*) malloc(sizeof(BiNode));//根
(*root)->pLeftChild = NULL;
(*root)->pRightChild = NULL;
(*root)->value = input;
//生成根节点
CreateBiTree1( &(*root)->pLeftChild );//生成左子树
CreateBiTree1( &(*root)->pRightChild );//生成右子树
}
//逐层遍历,从左到右, 打印出关系图
void LayerPrint(BiNode *root)
{
if(root == NULL)
{
}
queue<BiNode *> store;
store.push(root);
int cur_layer_num = store.size();
while(!store.empty())
{
int next_layer_num = 0;
for(int i = 1; i <= cur_layer_num; i++)
{
BiNode * temp = store.front();//取出最上层
printf("%d ", temp->value);
if(temp->pLeftChild != NULL)
{
store.push(temp->pLeftChild);//保存本节点的各个子节点
next_layer_num++;
}
if(temp->pRightChild != NULL)
{
store.push(temp->pRightChild);
next_layer_num++;
}
store.pop();//弹出最上层
}//本层处理完,下层的子节点也保存了下来
cur_layer_num = next_layer_num;
}
}
//先序递归
void prePrint(BiNode* root)
{
if(root == NULL)
return;
printf("%d ", root->value);
prePrint(root->pLeftChild);
prePrint(root->pRightChild);
}
/*非递归*/
void prePrint_nonRecusive(BiNode* root)
{
if(root == NULL)
return ;
BiNode *cur = root;
int state = 0;
stack<BiNode*> store;
while(1)
{
if(!cur)
{
//if(cur == root) break;
//或者
if(store.empty()) break;
cur = store.top();//如果当前节点为空,则返回上一层
state = cur->state;//获取当前节点的状态
store.pop();//弹出该层
}
else if(state == 0)//打印当前节点,压入栈中
{
printf("%d ", cur->value);//打印根节点
cur->state = 1;
store.push(cur);//压入该层的节点
cur = cur->pLeftChild;//指向左节点
state = 0;//继续往左,打印,添加新的左边节点
}
else if(state == 1)//转向右边节点
{
cur->state = 2;//判断以当前节点为根节点,是否已经结束
store.push(cur);
cur = cur->pRightChild;
state = 0;
}
else if(state == 2)//如果,返回上一层节点
{
//if(cur == root) break;
//或者
if(store.empty()) break;
cur = store.top();
state = cur->state;
store.pop();//弹出
}
}
}
//中序递归
void midPrint(BiNode* root)
{
if(root == NULL)
return;
midPrint(root->pLeftChild);
printf("%d ", root->value);
midPrint(root->pRightChild);
}
/*非递归*/
void midPrint_nonRecusive(BiNode* root)//中序遍历
{
if(root == NULL)
return;
int state = 0; //打印左子树,根,右子树
BiNode* cur = root;
stack<BiNode*> store;
while(1)
{
if(!cur)//如果为空,则返回上一层
{
if(cur == root) break;
cur = store.top();
state = cur->state;
store.pop();
}
if(state == 0)//表示保存本节点入栈, 指向左孩子
{
cur->state = 1;
store.push(cur);//压入栈,表示下次进入时,已当前节点为根节点,完成左边子树状态
cur = cur->pLeftChild;//第一次进入左孩子
state = 0;
}
else if(state == 1)//表示已当前节点为根节点,完成左边子树状态
{
cur->state = 2;
store.push(cur);//以其为根节点,右子树完成的状态
cur = cur->pRightChild;//第一次进入右孩子
state = 0;//添加新节点状态
}
else if(state == 2)//以当前节点为根节点的树,遍历完成 (完成右子树)
{
if(root == cur) break;
//打印本层的根节点
printf("%d ", cur->value);
cur = store.top();//返回上一层
state = cur->state;//恢复该节点的状态
store.pop();
}
}
}
//后序递归
void postPrint(BiNode* root)
{
if(root == NULL)
return;
postPrint(root->pLeftChild);
postPrint(root->pRightChild);
printf("%d ", root->value);
}
/*非递归*/
void postPrint_nonRecusive(BiNode* root)
{
if(root == NULL)//左子树,右子树,根
return;
int state = 0;
BiNode *cur = root;
stack<BiNode*> store;
while(1)
{
if(!cur)//返回上一层
{
cur = store.top();
state = cur->state;//恢复出栈
store.pop();
}
else if(state == 0)//保存当前节点,进入左子树
{
cur->state = 1;
store.push(cur);
cur = cur->pLeftChild;
state = 0;//继续往左遍历
}
else if(state == 1)//表示以当前节点为根节点,完成左子树,进入到右子树
{
cur->state = 2;
store.push(cur);
cur = cur->pRightChild;
state = 0;
}
else if(state == 2)//表示已当前节点为根的树,遍历完成
{
//返回上一层
printf("%d ", cur->value);
if(cur == root) break;
cur = store.top();
state = cur->state;
store.pop();
}
}
}
测试文件:
// BiTree.cpp : 定义控制台应用程序的入口点。
//
#include"CreateBiTree.h"
#include<stdio.h>
/*
8
/ \
/ \
6 10
/ \ / \
5 7 9 11
*/
int main(int argc, char* argv[])
{
BiNode* root;
printf("输入数据:\n");
CreateBiTree1(&root);
//输入 8,6,5,(继续往左)-1(返回上一层状态),(向右)-1(返回上一层),7,(向左)-1(返回上一层状态),(向右)-1(返回上一层),10,9,(向左)-1(返回上一层),(向右)-1(返回上一层),11,-1,-1
printf("层次打印:\n");
LayerPrint(root);
printf("\n先序打印:\n");
prePrint(root);
printf("\n中序打印:\n");
midPrint(root);
printf("\n后序打印:\n");
postPrint(root);
/*非递归版本*/
printf("\n非递归,先序打印:\n");
prePrint_nonRecusive(root);
printf("\n非递归,中序打印:\n");
midPrint_nonRecusive(root);
printf("\n非递归,后序打印:\n");
postPrint_nonRecusive(root);
return 0;
}

浙公网安备 33010602011771号