二叉树基础技巧
二叉树需要返回值的算法题大多基于前中后三递归顺序,其中前序递归可以认为成自上而下,后序递归为自下而上;无返回值,使用全局变量算法题直接理解为(先序、后序)遍历会比递归更加容易。
由于一般将递归解释为函数调用自身,所以上述其实都是函数递归过程。本文又细分遍历、递归仅为方便理解,因为递归本身就是更强的循环遍历,只是借助于栈的结构,而无返回值的递归更类似于遍历(普通的循环就没有从内部向外的返回值,只能先在语句块外定义变量,然后从循环中带出某些信息,类似全局变量),如遍历树和图使用函数递归,但称之为深度优先遍历(搜索)。
先中后三种顺序就是看当前结点的处理位于两个递归调用函数的哪个位置,之前链表一文的先序后序也是看当前结点在递归调用函数的哪个位置。
简单总结就是当前结点的处理与递归调用的相对位置导致顺序的概念,而函数的有无返回值特征使得理解方式不同。
递归与遍历角度
leetcode222:完全二叉树结点个数
1.先序递归
class Solution{
public:
int countNodes(TreeNode* cur){
if(cur==NULL) return 0;
int num=1;//先序递归
num+=countNodes(cur->left);
num+=countNodes(cur->right);
return num;
}
};
2.后序递归
class Solution {
public:
int countNodes(TreeNode* root) {
if(!root) return 0;
int leftnum = countNodes(root->left);
int rightnum = countNodes(root->right);
int num = leftnum+rightnum+1;//后序递归
return num;
}
};
3.先序遍历(同样有后序遍历)
class Solution {
public:
int num=0;//类似全局变量
int countNodes(TreeNode* root) {
count(root);
return num;
}
void count(TreeNode* root){
if(!root) return ;
num++;//先序遍历好理解,推荐
count(root->left);
count(root->right);
//num++;后序遍历
}
};
leetcode111:二叉树的最小深度
leetcode104二叉树最大深度的进阶版
递归(简略版前后序已经看不出来了,因为如果写开都是可以的)
class Solution{
public:
int minDepth(){
if(!root) return 0;
if(root->left==NULL&&root->right) return 1+minDepth(root->right);
if(root->right==NULL&&root->left) return 1+minDepth(root->left);
return 1+min(minDepth(root->left),minDepth(root->right));
}
};