/*
分层遍历二叉树:
1给定一颗二叉树,要求按分层遍历该二叉树,即从上到下按层次访问该二叉树(每一层将单独输出一行),每一层要求访问的顺序为从左到右,并将节点依次编号,
那么分层遍历如下的二叉树,正确的输出应该为
1
2 3
4 5 6
7 8
1
2 3
4 5 6
7 8
2写另外一个函数,打印二叉树中某层次的节点(从左到右),其中根节点为第0层,函数原型为int PrintNodeAtLevel(Node* root,int level),成功返回1,
失败返回0
假设要求放分二叉树中第k层的节点,那么其实可以把它转换成分别访问"以该二叉树根节点的左右子节点为根节点的两棵子树"中层次为k-1的节点,如题目中的
二叉树,给定k=2,即要求访问原二叉树中第2层的节点(根节点为第0层),可把它转换成分别访问以节点2,3为根节点的两棵子树中第k-1 = 1层的节点
1
2 3
4 5 0 0
6 7 8 9
0 0 0 0 0 0 0 0
输入:
19
1 2 4 6 0 0 7 0 0 5 8 0 0 9 0 0 3 0 0
输出:
1
2 3
4 5
6 7 8 9
*/
/*
关键:
1 if(!pRoot || iLevel < 0)
{
return 0;//这个返回值,非常有用,用于无法知道树的深度的情况下,当无法遍历某一层次的输出
2 if(iLevel == 0)//递归出口
{
printf("%d ",pRoot->_iVal);
return 1;
}
3 return printNodeAtLevel(pRoot->_pLeft,iLevel-1) + printNodeAtLevel(pRoot->_pRight,iLevel-1);//注意返回的是当前层次下所有子节点个数
4 for(int iLevel = 0 ; ; iLevel++)//效率差,每次访问都需要从根节点重新遍历
{
if(!printNodeAtLevel(pRoot,iLevel))//当访问到某一层次失败就可以退出了。当level小于0的时候
{
break;
5 在访问第k层的时候,我们需要知道第k-1层的节点信息,所以再访问第k层的时候,要是知道第k-1层的节点信息,就不需要从根节点开始遍历
可以从根节点除法,将每一层的节点从左到右压入一个数组,并用一个游标cur记录当前访问的节点,另一个游标last表示当前层次最后一个节点的下一个位置。
以cur = last表示当前层次访问结束,在访问某一层的同时将该层所有节点的子节点压入数组,在访问完某一层之后,检查是否还有新的层次可以访问,直到
访问完所有的层次。
6 int iCur = 0,iLast = 1;//初始化游标起始位置和当前层结束位置的下一个位置
7 while(iCur < vecNode.size())//这里应该是层结束位置等于数组大小的时候结束循环
8 iLast = vecNode.size();//牛逼,直接用当前层结束位置的下一位置 等于 向量大小 来解决了每次的更新层结束位置的问题
while(iCur < iLast)
*/
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;
const int MAXSIZE = 10000;
typedef struct Node
{
int _iVal;
Node* _pLeft,*_pRight;
}Node;
Node g_nodeArr[MAXSIZE];
int g_iIndex;
Node* createNode()
{
++g_iIndex;
g_nodeArr[g_iIndex]._pLeft = g_nodeArr[g_iIndex]._pRight = NULL;
return &g_nodeArr[g_iIndex];
}
Node* buildTree(int* pArr,int iLen,int& iPos)
{
if(!pArr || iLen < 0 || iPos < 0)
{
return NULL;
}
Node* pRoot;
if(pArr[iPos] == 0)//如果是叶节点
{
iPos++;
return NULL;
}
if(iPos < iLen)//如果还没有超过长度,持续建立
{
pRoot = createNode();
pRoot->_iVal = pArr[iPos++];
pRoot->_pLeft = buildTree(pArr,iLen,iPos);
pRoot->_pRight = buildTree(pArr,iLen,iPos);
}
return pRoot;
}
//返回的是某一层下面的节点总数
int printNodeAtLevel(Node* pRoot,int iLevel)
{
if(!pRoot || iLevel < 0)
{
return 0;//这个返回值,非常有用,用于无法知道树的深度的情况下,当无法遍历某一层次的输出
}
if(iLevel == 0)//递归出口
{
printf("%d ",pRoot->_iVal);
return 1;
}
return printNodeAtLevel(pRoot->_pLeft,iLevel-1) + printNodeAtLevel(pRoot->_pRight,iLevel-1);//注意返回的是当前层次下所有子节点个数
}
void printLevelNode_withoutDepth(Node* pRoot)//访问二叉树某一层次失败的时候返回就可以了
{
for(int iLevel = 0 ; ; iLevel++)//效率差,每次访问都需要从根节点重新遍历
{
if(!printNodeAtLevel(pRoot,iLevel))//当访问到某一层次失败就可以退出了。当level小于0的时候
{
break;
}
printf("\n");
}
}
void printLevelNode(Node* pRoot,int iDepth)
{
for(int i = 0 ; i < iDepth ; i++)//打印每一层的节点
{
printNodeAtLevel(pRoot,iDepth);
}
}
/*
在访问第k层的时候,我们需要知道第k-1层的节点信息,所以再访问第k层的时候,要是知道第k-1层的节点信息,就不需要从根节点开始遍历
可以从根节点除法,将每一层的节点从左到右压入一个数组,并用一个游标cur记录当前访问的节点,另一个游标last表示当前层次最后一个节点的下一个位置。
以cur = last表示当前层次访问结束,在访问某一层的同时将该层所有节点的子节点压入数组,在访问完某一层之后,检查是否还有新的层次可以访问,直到
访问完所有的层次。
首先将根节点1压入数组,将游标cur置为0,游标last置为1,因为当cur = last = 1时,第0层访问结束。当cur < last,说明此层尚未被访问完,因此依次访问
cur到last之间的所有节点,并依次将被访问节点的左右子节点压入数组,当放完问第一层时,cur = 1,
cur == last ,盖层访问完,此时数组中还有尚未被访问到的节点,则输出换行符(为输出新的一行做准备),并将Last定位与新一行的末尾(即数组当前最后一个
元素的下一位),继续依次访问其他层次的节点,知道所有层次访问结束。
*/
void printLevelNode_index(Node* pRoot)
{
int iCur = 0,iLast = 1;//初始化游标起始位置和当前层结束位置的下一个位置
vector<Node*> vecNode;
vecNode.push_back(pRoot);
while(iCur < vecNode.size())//这里应该是层结束位置等于数组大小的时候结束循环
{
iLast = vecNode.size();//牛逼,直接用当前层结束位置的下一位置 等于 向量大小 来解决了每次的更新层结束位置的问题
while(iCur < iLast)
{
Node* pNode = vecNode[iCur];
printf("%d ",pNode->_iVal);//应该先打印出当前节点值
if(pNode->_pLeft)
{
vecNode.push_back(pNode->_pLeft);
}
if(pNode->_pRight)
{
vecNode.push_back(pNode->_pRight);
}
iCur++;
}
printf("\n");
}
}
void process()
{
int n;
while(EOF != scanf("%d",&n))
{
int iArr[MAXSIZE];
for(int i = 0 ; i < n ; i++)
{
scanf("%d",&iArr[i]);
}
int iPos = 0;
g_iIndex = 0;
memset(g_nodeArr,NULL,sizeof(g_nodeArr));
Node* pRoot = buildTree(iArr,n,iPos);
//printLevelNode_withoutDepth(pRoot);
printLevelNode_index(pRoot);
}
}
int main(int argc,char* argv[])
{
process();
getchar();
return 0;
}
编程之美:第三章 结构之法 3.10分层遍历二叉树
最新推荐文章于 2022-09-17 21:26:14 发布