题目:写一个函数,打印二叉树中某层次的节点(从左到右),其中根节点为第0层,函数原型为int PrintNodeAtLevel(Node* root, int level),成功返回1,失败返回0。
(一)递归解法
思路分析:假设要求访问二叉树中第K层的节点,那么可以把它转换成访问以“该二叉树根节点的左右节点”为根的两颗左右子树的第K-1层的节点。依次递归,直到k=0时,输出节点即可。
(二)非递归解法
前面几篇博客已经讲述了“ 二叉树的层序遍历、层序打印”,同样的思想,我们稍作修改即可。
具体实现如下:
注意点:第 k 层节点,位于(k-1)层;(例如,根节点位于 0 层,即第1层)
#include <iostream>
using namespace std;
#include <vector>
#include <deque>
typedef struct node
{
char data;
struct node *lchild;
struct node *rchild;
}BiNode, *BiTree;
// 先序建立二叉树 (输入时,按先序次序输入二叉树中结点的值,以 # 字符表示空树)
BiTree createBiTree()
{
BiTree T;
char c;
scanf("%c", &c);
if (c == '#')
T = NULL;
else
{
T = new BiNode; // 或 T = (BiTree)malloc(sizeof(BiNode));
T->data = c;
T->lchild = createBiTree();
T->rchild = createBiTree();
}
return T;
}
// (递归1),输出二叉树某一层结点(从左到右)
int PrintNodeAtLevel1(BiTree T , int level) // 参数level代表几层(不是第几层)
{
if(T == NULL || level < 0)
return 0;
if(level == 0)
{
printf("%c ", T->data);
return 1;
}
return PrintNodeAtLevel1(T->lchild,level-1) + PrintNodeAtLevel1(T->rchild,level-1);
}
// (递归2),输出二叉树某一层结点(从左到右)[递归1的缺点:return a() + b()似乎不能保证从左往右输出,因为a() + b()的调用顺序是由编译器决定的,并不一定是从左往右。如果打印时一定需要返回值,对“递归2”做适当修改即可]
void PrintNodeAtLevel(BiTree T , int level) // 参数level代表几层(不是第几层)
{
if(T == NULL || level < 0) return ;
if(level == 0)
{
printf("%c ", T->data);
}
PrintNodeAtLevel(T->lchild , level - 1);
PrintNodeAtLevel(T->rchild , level - 1);
}
// 非递归(一),此处借助vector来实现。
void printNodeAtLevel2(BiTree T, int level) // 参数level代表几层(不是第几层)
{
if (T == NULL) return;
vector<BiTree> vec;
vec.push_back(T);
int curLevel = 0; // 当前位于几层;(注意是几层,不是第几层;例如,根节点位于0层,即第1层)
int cur = 0;
int last = 1;
while (cur < vec.size() && curLevel < level)
{
last = (int)vec.size();
while (cur < last)
{
if (vec[cur]->lchild)
vec.push_back(vec[cur]->lchild);
if (vec[cur]->rchild)
vec.push_back(vec[cur]->rchild);
cur++;
}
curLevel++; // 当前层数加1
}
for (int i = cur; i < vec.size(); i++) {
printf("%c ", vec[i]->data);
}
}
// 非递归(二),此处借助queue来实现。
void printNodeAtLevel3(BiTree T, int level) // 参数level代表几层(不是第几层)
{
if(T == NULL) return;
deque<BiTree> q;
q.push_back(T);
int curLevelNum; // 当前层的节点数
int curLevel = 0; // 当前位于几层
while (q.size() && curLevel < level)
{
curLevelNum = (int)q.size(); // 此处要做类型转换,因为size()返回值为size_type类型;
while(curLevelNum-- > 0) // 一直访问到当前层的最后一个节点
{
BiTree tmp = q.front();
q.pop_front();
if(tmp->lchild)
q.push_back(tmp->lchild);
if(tmp->rchild)
q.push_back(tmp->rchild);
}
curLevel++; // 当前层数加1
}
for (int i = 0; i < q.size(); i++) {
printf("%c ", q[i]->data);
}
}
int main(int argc, const char * argv[]) {
BiTree T = createBiTree(); // 建立
// PrintNodeAtLevel1(T, 2); // 递归输出
// printNodeAtLevel2(T, 2); // 非递归
printNodeAtLevel3(T, 2); // 非递归
return 0;
}