3.10 分层遍历二叉树
问题描述:
1、给定一棵二叉树,要求按分层遍历该二叉树,
即从上到下按层次访问该二叉树(每一层将单独输出一行),
每一层要求访问的顺序为从左到右,
并将节点依次编号。下面是一个例子:
8
/ \
6 10
/ \ / \
5 7 9 11
打印出来:
8
6 10
5 7 9 11
2、写另外一个函数,打印二叉树中某层次的节点(从左到右),其中根节点为第0层,;
分析与解法
方法一:
输出二叉树某一层结点(从左到右)
递归实现,把输出二叉树第K层结点转换成:分别输出"以该二叉树根结点的左右子树为根的两棵子树"中第K-1层结点。
void PrintNodeAtLevel(Node *root , int level)
{
if(!root || level < 0)
return ;
if(level == 0)
{
printf("%c", root->chValue);
}
PrintNodeAtLevel(root->lChild , level - 1);
PrintNodeAtLevel(root->rChild , level - 1);
}
以上输出某一层节点,若知道深度n,只需调用n次即可;
void printNodeByLevel(Node *root,int depth)
{
for(int level=0;level<depth;level++)
{
printNodeAtLevel(root,level);
cout<<endl;
}
}
方法二
按层从上到下遍历二叉树,每一层单独一行且从左往右输出,
BFS,用队列实现 ,具体实现见后面代码
扩展问题
1、依然是按层遍历二叉树,只是要求从下往上访问,
并且每一层中结点的访问顺序为从左向右
类似扩展问题2,输出时处理下 ,具体见后面实现
2、依然是按层遍历二叉树,只是要求从下往上访问,
并且每一层中结点的访问顺序为从右向左
分析:只要层与层之间加入哑元素(NULL),然后逆序输出队列Q即可
第一步:给每一层之间添加哑元素NULL
第二步:逆序输出队列Q
代码实现
/*
8
/ \
6 10
/ \ / \
5 7 9 11 */
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<queue>
using namespace std;
#define MAX 20
struct BTreeNode{
int data;
BTreeNode *left,*right;
};
//建立二叉树
BTreeNode * CreateTree(int data[],int pos,int len)
{
BTreeNode *tree;
if(pos>=len)
{
return NULL;
}
else
{
tree=(BTreeNode *)malloc(sizeof(BTreeNode));
tree->data=data[pos];
tree->left=CreateTree(data,2*pos+1,len);//数组坐标
tree->right=CreateTree(data,2*pos+2,len);
return tree;
}
}
//中序遍历
void InOrder(BTreeNode *tree)
{
if(tree!=NULL)
{
InOrder(tree->left);
printf("%d ",tree->data);
InOrder(tree->right);
}
}
// BFS层次遍历
void BFS(BTreeNode *root)
{
BTreeNode *temp,*start;
queue<BTreeNode *> q;
q.push(root);
while(!q.empty())
{
start=q.front();
q.pop();
if(start->left!=NULL)
q.push(start->left);
if(start->right!=NULL)
q.push(start->right);
printf("%d ",start->data);
}
}
//方法二:用数组模拟 队列;方便实现扩展问题
void BFS1(BTreeNode *root)
{
BTreeNode *p;
BTreeNode *Q[200];
int front,rear,last;
if(!root)
return ;
front=rear=0;
Q[rear++]=root;
Q[rear++]=NULL;
while(front<rear-1)
{
last=rear-1;
while(front<last)
{
p=Q[front++];
if(p->left!=NULL)
Q[rear++]=p->left;
if(p->right!=NULL)
Q[rear++]=p->right;
}
Q[rear++]=NULL;
front=last+1;
}
printf("\n层次遍历 打印结果:\n");
for(int i=0;i<=rear-2;i++)
{
if(Q[i]==NULL)
printf("\n");
else
printf("%d ", Q[i]->data);
}
printf("\n扩展问题1 打印结果:\n");
int j,k;
for(int i=rear-2;i>=0;i--)
{
if(Q[i]==NULL)
{
printf("\n");
for(j=i-1;j>=0;j--)
if(Q[j]==NULL)
break;
for(k=j+1;k<i;k++)
printf("%d ", Q[k]->data);
i=j+1;
}
}
printf("\n扩展问题2 打印结果:\n");
for(int i=rear-2;i>=0;i--)
{
if(Q[i]==NULL)
printf("\n");
else
printf("%d ", Q[i]->data);
}
}
int main(){
int data[]={8,6,10,5,7,9,11};
int len=sizeof(data)/sizeof(int);
BTreeNode *tree=CreateTree(data,0,len);
printf("中序遍历:\n");//左根右
InOrder(tree);printf("\n");
printf("BFS层次遍历 打印结果:\n");
BFS(tree);printf("\n");
BFS1(tree);
return 0;
}
8
/ \
6 10
/ \ / \
5 7 9 11