译文描述
从上往下打印出二叉树的每个副本,同层中断从左至右打印。
其实就是层次遍历,这个我们在我之前的文章博客里面将的很清楚了
其中调试的时候使用了
剑指优惠--006-改造二叉树来辅助我们通过前序和中序遍历的序列来生成二叉树
直接粘贴代码,只需要直接将我们层次遍历输出过程,变成将输入压入vector中即可
#包括 < iostream >
#包括 <向量>
#包括 < deque >
#包括 <类别>
使用 名称空间 std ;
// 调试开关
#定义 __tmain主
#IFDEF __tmain
#定义 调试指令
#其他
#定义 调试 0 && cout
#ENDIF // __tmain
#定义 undebug 0 && cout
#IFDEF __tmain
结构 树节点
{
int val;
struct TreeNode *左;
struct TreeNode *正确;
TreeNode( int x)
:val(x),左(NULL),右(NULL)
{
}
};
#ENDIF // __tmain
类 解决方案
{
向量< int > res;
public:
vector < int > PrintFromTopToBottom(TreeNode *根)
{
// /方法1-=>循环调用递归打印每一层
LevelOrder(根);
// /方法2-=>使用两个双端
层次LevelOrderDev(根);
// /方法3-=>使用双指针标识当前指针和结束
LevelOrderUsePoint(根);
// /方法4-=>使用aprent和childzsizesize标识前一层和当前层的路由器
个数LevelOrderUseSize(根);
// /方法4-=>在层次中插入结束标识来标识当前层结束
LevelOrderUseEnd(根);
返回 此 ->水库;
}
// /打印某些层的例程,递归实现
int PrintLevel(TreeNode * root, int 等级)
{
如果(root == NULL || 等级< 0)
{
返回 0 ;
}
否则 ,如果(水平== 0)
{
调试<< root-> val ;
水库push_back(root-> val); // /在向量中添加结果
返回 1 ;
}
其他
{
返回 PrintLevel(root->左, level- 1)+ PrintLevel(root->右, level- 1);
}
}
// /循环每层输出其例程,调用递归归零函数
void LevelOrder(TreeNode * root)
{
水库清除(); // /将结果加到向量中
if(root == NULL)
{
奖励 ;
}
对于( int level = 0 ;; ++级)
{
如果( PrintLevel(根,级别)== 0)
{
休息 ;
}
调试<< endl;
}
}
// ////////////////////////
// /使用两个双端队列
// ///////////// ///////////
void LevelOrderDev(TreeNode *根)
{
水库清除(); // /在向量中添加结果
// / deque双端高分子,
// /支持继承器,有push_back()方法,
// /跟vector差不多,比vector多了个pop_front,push_front方法
deque <TreeNode *> qFirst,qSecond;
q首先。的push_back(根);
而(qFirst。空()!=真)
{
而(qFirst。空()!=真)
{
TreeNode * temp = qFirst。前();
q首先。pop_front();
调试<< temp-> val ;
水库push_back(temp-> val); // /在向量中添加结果
如果(temp-> left!= NULL)
{
q第二。push_back(temp-> 左);
}
如果(temp-> right!= NULL)
{
q第二。push_back(temp-> right);
}
}
调试<< endl;交换(qSecond);
q首先。
}
}
// //////////////////////
///使用双指针标识当前指针和结束
// /////////// // ///////////
void LevelOrderUsePoint(TreeNode *根)
{
水库清除(); // /在向量中添加结果
向量<TreeNode *> vec;
。VEC 的push_back(根);
int cur = 0 ;
int end = 1;
而(CUR <VEC。大小())
{
结束= vec。大小(); // /新的一行访问开始,重新定位end于当前行最后一个例程的下一个位置
一会儿(cur <结束)
{
调试<< vec [cur]-> val ; // _ /访问股东
资源。push_back(vec [cur]-> val); // /在向量中添加结果
if(vec [cur]-> left!= NULL) // /压入左例程
{
。VEC 的push_back(VEC [CUR] - > 左);
}
if(vec [cur]-> right!= NULL) // /压入右例程
{
。VEC 的push_back(VEC [CUR] - > 右);
}
cur ++;
}
调试<< endl;
}
}
// ///////////////////////
///使用aprent和childzsizesize标识前一层和当前层的例程个数
// //// //////////////////
void LevelOrderUseSize(TreeNode *根)
{
水库清除(); // /在向量中添加结果
int parentSize = 1,childSize = 0;
TreeNode * temp = NULL ;
队列<TreeNode *> q;
q。推(root);
而(q。空()!= true)
{
温度= q 前();
调试<< temp-> val ;
水库push_back(temp-> val); // /在向量中添加结果
q。踢();
如果(temp-> left!= NULL)
{
q。推(temp-> left);
childSize ++;
}
如果(temp-> right!= NULL)
{
q。推(temp-> right);
childSize ++;
}
parentSize--;
如果(parentSize == 0)
{
parentSize = childSize;
childSize = 0 ;
调试<< endl;
}
}
}
// ////////////////////////
// /在队列中插入结束标识来标识当前层结束
// //////// //////////////
void LevelOrderUseEnd(TreeNode *根)
{
水库清除(); // /在向量中添加结果
队列<TreeNode *> q;
q。推(root);
q。按下(NULL);
而(q。空()!= true)
{
TreeNode *基线= q。前();
:Q 弹出();
如果(议)
{
调试<< node-> val ;
水库push_back(node-> val); // /在向量中添加结果
如果(node-> left!= NULL)
{
q。推(node-> left);
}
如果(node-> right!= NULL)
{
q。推(node-> right);
}
}
否则 ,如果(Q。空()!=真)
{
q。按下(NULL);
调试<< endl;
}
}
}
struct TreeNode * reConstructBinaryTree(向量< int > pre,向量< int > in)
{
// 前序遍历的长度跟中序遍历的长度应该相同
,如果(前。大小()!= IN。大小())
{
取消调试<< “ PRE和IN的长度应为smae ” << endl;
返回 NULL ;
}
//长度不能为0
int size = pre。大小();
如果(大小== 0)
{
undebug << “这是一个NULL树(长度= 0)” << endl;
返回 NULL ;
}
int length = pre。大小();
解除调试<< “树的长度= ” << length << endl;
int值= pre [ 0 ]; // 前序遍历的第一个结点是根节点
TreeNode * root = new TreeNode(值);
解除调试<< “的根是” << root-> val << endl;
// 在中序遍历中查找到根的位置
int rootIndex = 0 ;
对于(rootIndex = 0 ; rootIndex <长度; rootIndex ++)
{
如果(在[rootIndex] ==值中)
{取消调试<< “,在IN ” << endl 中的“ << rootIndex
<< ”找到根;
休息 ;
}
}
如果(rootIndex> =长度)
{
取消调试<< “不能在IN ” << endl中找到根(值= “ << value << ”));
返回 NULL ;
}
// /区分左子树和右子树
// /中序遍历中,根左边的就是左子数,右边的就是右子树
// / /前序遍历中,根后面是先遍历左子树,然后是右子树
// /首先确定左右子树的长度,从中中序遍历in中确定
int leftLength = rootIndex;
int rightLength =长度 -1 -rootIndex;解除调试
<< “ left length = ” << leftLength << “,rightLength = ” << rightLength << endl;
向量< int > preLeft(leftLength),inLeft(leftLength);
向量< int > preRight(rightLength),inRight(rightLength);
对于(int = 0 ; 我<长度; 我++)
{
如果(i <rootIndex)
{
// 前序遍历的第一个是根目录,根后面的(leftLegnth = rootIndex)-1个例程是左子树,因此是i + 1
preLeft [i] = pre [i + 1 ];
// 中序遍历前(leftLength = rootIndex)-1个例程是左子树,第rootIndex个例程是根
inLeft [i] = in [i];
取消调试<< preLeft [i] << inLeft [i] << “ ” ;
}
否则 如果(I> rootIndex)
{
// 前序遍历的第一个是根子系统,根后面的(leftLegnth = rootIndex)-1个例程是左子树,后面是右子树
preRight [i-rootIndex- 1 ] = pre [i];
// 中序遍历前(leftLength = rootIndex)-1个例程是左子树,第一个rootIndex个例程是根,然后是右子树
inRight [i-rootIndex- 1 ] = in [i];
取消调试<< preRight [i-rootIndex- 1 ] << inRight [i-rootIndex- 1 ] << “ ”;
}
}
解除调试<< endl << “左树” << endl;
对于(int i = 0 ; 我<leftLength; 我++)
{
取消调试<< preLeft [i] << inLeft [i] << “ ” ;
}
解除调试<< endl;
解除调试<< “正确的树” << endl;
对于(int i = 0 ; 我<rightLength; 我++)
{
取消调试<< preRight [i] << inRight [i] << “ ” ;
}
解除调试<< endl;
root-> left = reConstructBinaryTree(preLeft,inLeft);
root-> right = reConstructBinaryTree(preRight,inRight);
返回根
}
};
int __tmain()
{
INT预[] = { 1, 2, 4, 7, 3, 5, 6, 8 };
INT中[] = { 4, 7, 2, 1, 5, 3, 8, 6 };
向量< int > preOrder(pre,pre + 8);
向量< int > inOrder(in,in + 8);
解决方案
树节点*根=解决方案。reConstructBinaryTree(预购,序);
溶PrintFromTopToBottom(根);
返回 0 ;
}