二叉树在学习数据结构中的重要性就不言而喻了,这儿简单记录一下自己碰到的一些关于二叉树的常见操作。当然要明确解决这些问题的“根节点思路”了————递归递归recursion。
最大深度是指二叉树根节点到该树叶子节点的最大路径长度。而最小深度自然就是其到叶子节点的最小路径长度了。
**主要思路:**采用二叉树递归的思想,自底向上,当到达叶子节点时,自然达到了“递归边界”,而叶子节点的子节点自然为NULL,也就是深度为0,所以叶子节点的深度自然就是0+1=1了,以此向上累加,并且判断最大值,自然就得到了其最大深度。
二叉树的最大深度:给定一个二叉树,找出其最大深度。
思路如上,具体实现如下:
int res=1;
int maxDepth(TreeNode* root) {
if(root==NULL)
return 0;
int d1=maxDepth(root->left);
int d2=maxDepth(root->right);
return max(d1,d2)+1;
}
二叉树的最小深度说明:与最大深度类似,无非把max改为min就行了。
这一类问题我觉得可以总结为“递归遍历节点并判断”,也是通过递归一个节点一个节点地进行比较。
相同的树:给定两个二叉树,编写一个函数来检验它们是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
**思路:**这道题最开始我是求出两个树的前序和中序遍历进行比较判断,但这种方法会有一些例外判断不到。最后还是直接递归地一个点一个点地判断。
bool isSameTree(TreeNode* p, TreeNode* q) {
if(p!=NULL&&q!=NULL){
if(p->val!=q->val)
return false;
else
return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
}
else{
if(p==NULL&&q==NULL)
return true;
else
return false;
}
}
对称二叉树:给定一个二叉树,检查它是否是镜像对称的。
递归向下检查,具体实现如下:
bool isSymmetric(TreeNode* root) {
if(!root)
return true;
return isSymmetric(root->left,root->right);
}
bool isSymmetric(TreeNode *left,TreeNode *right){
if(!left&&!right)
return true;
if((left&&!right)||(!left&&right)||(left->val!=right->val))
return false;
return isSymmetric(left->left,right->right)&&isSymmetric(left->right,right->left);
}
翻转二叉树:将二叉树翻转(左变右,右变左)。
这个问题也算是出名过头了,参见Google那档子奇闻轶事,也很简单,怎么交换两个数的值就怎么翻转,只不过交换的东西从 int 变成了 Tree 而已。
TreeNode* invertTree(TreeNode* root) {
if(!root)
return NULL;
TreeNode *tem;
tem=root->left;
root->left=root->right;
root->right=tem;
invertTree(root->left);
invertTree(root->right);
return root;
}
二叉树的最近公共祖先:给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
**思路:**先遍历得到二叉树从根节点到目标节点的路径(形成一个链表),再找到两个链表中最后一个相同节点,即为其最近公共祖先。具体实现如下:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root==NULL)
return NULL;
vector pp,qq,tem;
bool flag=false;
getList(root,p,tem,pp,flag);
flag=false;
getList(root,q,tem,qq,flag);
int size=pp.size()>qq.size()?qq.size():pp.size();
int i=0;
for(i;i &res,vector &path,bool flag){
if(root==NULL||flag)
return;
res.push_back(root);
if(root==target){
flag=true;
path=res;
}
getList(root->left,target,res,path,flag);
getList(root->right,target,res,path,flag);
res.pop_back();
}
路径总和 II :给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。
**思路:**依然是采用递归的方式,每次判空后用目标和减去该节点的值同时将该节点的值压入tem向量,当目标和为0时,将该tem向量压入结果向量res,完成其过程。
vector> res;
vector tem;
vector> pathSum(TreeNode* root, int sum) {
if(root==NULL)
return {};
int k=sum-root->val;
tem.push_back(root->val);
if(root->left==NULL&&root->right==NULL){
if(k==0){
res.push_back(tem);
}
}
pathSum(root->left,k);
pathSum(root->right,k);
tem.pop_back();
return res;
}
欢迎访问我的个人blog