树相关操作¶
1 树的结点定义¶
struct TreeNode{
int val;
TreeNode*left;
TreeNode*right;
TreeNode(int x):val(x),left(nullptr),right(nullptr){}
}
2 树的遍历¶
2.1 三种遍历方式¶
void traversal(TreeNode*root)
{
if(root!=nullptr)
{
//visit(root)前序操作
traversal(root->left);
//visit(root)中序操作
traversal(root->right);
//visit(root)后序操作
}
}
2.2 根据前+中序、后+中序构建二叉树¶
//前+中序
TreeNode*build(
vector<int>&preorder,int preL,int preR,
vector<int>&inorder,int inL,int inR,
unordered_map<int,int>&pos
)
{
if(preL>preR)return nullptr//递归返回条件
//确定根结点
int rootVal=preorder[preL];
TreeNode*root=new TreeNode(rootVal);
int k=pos[rootVal];//这里k就是中序序列中根所在的位置的下标
int leftSize=k-inL;
//这里可借助草稿确定新的边界范围
root->left=build(
preorder,preL+1,preL+leftSize,
inorder,inL,k-1,
pos
);
root->right=build(
preorder,preL+leftSize+1,preR,
inorder,k+1,inR,
pos
);
return root;
}
//后+中序
TreeNode*build(
vector<int>&postorder,int postL,int postR,
vector<int>&inorder,int inL,int inR,
unordered_map<int,int>&pos
)
{
if(postL>postR)return nullptr;//递归返回条件
//确定根结点
int rootVal=postorder[postR];
TreeNode*root=new TreeNode(rootVal);
int k=pos[rootVal];//这里k就是中序序列中根所在的位置的下标
int rightSize=inR-k;
//这里可借助草稿确定新的边界范围
root->left=build(
postorder,postL,postR-rightSize-1,
inorder,inL,k-1,
pos
);
root->right=build(
postorder,postR-rightSize,postR-1,
inorder,k+1,inR,
pos
);
return root;
}
而上述代码中涉及到哈希表pos的构建,因此整个二叉树的构建可以用下面的adapter函数来实现
TreeNode*buildTree(
vector<int>&preorder,
vector<int>&inorder
)
{
unordered_map<int,int>pos;
for(int i=0;i<inorder.size();i++)
{
pos[inorder[i]]=i;
}
return build(
preorder,0,preorder.size()-1,
inorder,0,inorder.size()-1,
pos
);
}
2.3 计算树的高度¶
int height(TreeNode*root)
{
if(root==nullptr)
{
return 0;
}
return max(height(root->left),height(root->right))+1;
}
2.4 平衡二叉树构建¶
2.5 线索二叉树¶
- 前序线索二叉树方便找后继,无法有效查找先序前驱
- 后序线索二叉树方便找前驱,无法有效查找后序后继
- 因为后序线索二叉树遍历为不断找后继的过程,因此其遍历仍需要栈的支持
2.6 WPL计算¶
void WPL(TreeNode*root,int layer,int &sum)
{
if(root==nullptr)
{
return;
}
if(root->left==nullptr&&root->right==nullptr)
{
sum+=(root->val)*layer;
}
WPL(root->left,layer+1,sum);
WPL(root->right,layer+1,sum);
}
递归中:
- 路径状态(path / layer / 当前和) → 一般不用 &,用值传递
- 全局累计量(答案 / 计数 / 最优值) → 用 & 或全局变量
