常见算法有:
- 求二叉树的最大深度
- 求二叉树的最小深度
- 二叉树的层次遍历
- 二叉树的前序遍历
- 二叉树的中序遍历
- 二叉树的后序遍历
- 求二叉树的节点个数
- 求二叉树的叶节点个数
- 判断二叉树是否为平衡二叉树
- 判断二叉树是否为满二叉树
- 判断两个二叉树是否完全相同
- 判断二叉树是否为二叉搜索树
- 将有序数组转换为二叉搜索树
- 镜像翻转二叉树
- 二叉树的“之”字形遍历
- 判断两个二叉树是否互为镜像
- 判断一个二叉树本身是否为镜像二叉树(对称二叉树)
- 求两个节点最近的公共祖先
- 判断两个节点是否为堂兄弟(深度相同且父节点不同)
- 二叉树中的最大路径和
(涉及到的相关概念不再赘述,在leetcode也可找到相关习题)
二叉树结构体定义:
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
1.求二叉树的最大深度
int maxDepth(TreeNode* root){
if (root == NULL) return 0;
int left = maxDepth(root->left);
int right = maxDepth(root->right);
return max(left, right) + 1;
}
2. 求二叉树的最小深度
int minDepth(TreeNode* root){
if (root == NULL) return 0;
return getMin(root);
}
int getMin(TreeNode* root){
if (root == NULL) return INT_MAX;
if (root->left == NULL && root->right == NULL) return 1;
return min(getMin(root->left), getMin(root->right)) + 1;
}
3. 二叉树的层次遍历
void levelView(TreeNode* root){
vector<int> s;
queue<TreeNode*> p, q;
p.push(root);
q = p;
while (!p.empty()){
p = queue<TreeNode*>();
s.clear();
while (!q.empty()){
TreeNode* tmp = q.front();
q.pop();
s.push_back(tmp->val);
if (tmp->left != NULL) p.push(tmp->left);
if (tmp->right != NULL) p.push(tmp->right);
}
for (auto i : s) cout << i << " ";
cout << endl;
q = p;
}
}
4. 二叉树的前序遍历
void preView(TreeNode* root){
if (root != NULL){
cout << root->val << " ";
preView(root->left);
preView(root->right);
}
}
5. 二叉树的中序遍历
void midView(TreeNode* root){
if (root != NULL){
midView(root->left);
cout << root->val << " ";
midView(root->right);
}
}
6. 二叉树的后序遍历
void postView(TreeNode* root){
if (root != NULL){
postView(root->left);
postView(root->right);
cout << root->val << " ";
}
}
7. 求二叉树的节点个数
int nodeNumbers(TreeNode* root){
if (root == NULL) return 0;
int left = nodeNumbers(root->left);
int right = nodeNumbers(root->right);
return left + right + 1;
}
8. 求二叉树的叶节点个数
int leafNodeNumbers(TreeNode* root){
if (root == NULL) return 0;
if (root->left == NULL && root->right == NULL) return 1;
return leafNodeNumbers(root->left) + leafNodeNumbers(root->right);
}
9. 判断二叉树是否为平衡二叉树
int countFloor(TreeNode* root){//计算层数
if (!root) return 0;
return 1 + max(countFloor(root->left), countFloor(root->right));
}
bool isBalanced(TreeNode* root) {
if (!root) return true;
if (abs(countFloor(root->left) - countFloor(root->right)) > 1) return false;
else return isBalanced(root->left) && isBalanced(root->right);
}
10. 判断二叉树是否为满二叉树
int countFloor(TreeNode* root){//计算层数
if (!root) return 0;
return 1 + max(countFloor(root->left), countFloor(root->right));
}
bool isFullTree(TreeNode* root){
if (root == NULL) return true;
TreeNode* tmp = root;
int floor = countFloor(tmp); //层数
int n = nodeNumbers(root) + 1; //满二叉树节点数为2^floor-1,利用算法7求节点数
while (n > 1){
if (n % 2 == 1) return false;
n /= 2;
floor -= 1;
if(floor == 0) break;
}
return n == 1;
}
//或者另一种方法:满二叉树的叶节点个数等于2^(层数-1)
bool isFullTree(TreeNode* root){
if (root == NULL) return true;
TreeNode* tmp = root;
int floor = countFloor(tmp); //层数
int leafNodes = leafNodeNumbers(root); //利用算法8求叶节点数
return leafNodes = pow(2, floor - 1);
}
11. 判断两个二叉树是否完全相同
bool isSameTree(TreeNode* p, TreeNode* q) {
if (!p && !q) return true;
if (q != NULL && p != NULL){
if (q->val != p->val) return false;
else return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
} else
return false;
}
12. 判断二叉树是否为二叉搜索树
void midView(TreeNode* p, vector<int> &s){
if (p){
midView(p->left, s);
s.push_back(p->val);
midView(p->right, s);
}
}
bool isValidBST(TreeNode* root) {
vector<int> s;
midView(root, s);
if (s.size() < 2) return true;
for (int i = 0; i < s.size() - 1; i++){
if (s[i] >= s[i + 1]) return false;
}
return true;
}
13. 将有序数组转换为二叉搜索树
TreeNode* buildTree(vector<int> &num, int left, int right) {
if (left > right) return NULL;
int mid = (left + right) / 2;
TreeNode* cur = new TreeNode(num[mid]);
cur->left = buildTree(num, left, mid - 1);
cur->right = buildTree(num, mid + 1, right);
return cur;
}
TreeNode* sortedArrayToBST(vector<int>& nums) {
return buildTree(nums, 0, nums.size() - 1);
}
14. 镜像翻转二叉树
TreeNode* invertTree(TreeNode* root) {
if (root != NULL){
TreeNode *tmp = root->left;
root->left = root->right;
root->right = tmp;
invertTree(root->left);
invertTree(root->right);
}
return root;
}
15. 二叉树的“之”字形遍历
vector<vector<int> > zigzagLevelOrder(TreeNode* root) {
vector<vector<int> > s;
bool change = false;
if (root == NULL) return s;
queue<TreeNode*> p;
p.push(root);
vector<int> t;
queue<TreeNode*> q = p;
t.push_back(root->val);
while (!q.empty()){
q = queue<TreeNode*>();
t.clear();
while (!p.empty()){
TreeNode* tmp = p.front();
t.push_back(tmp->val);
p.pop();
if (tmp->left != NULL) q.push(tmp->left);
if (tmp->right != NULL) q.push(tmp->right);
}
p = q;
if (change){
change = false;
reverse(t.begin(), t.end());
} else change = true;
s.push_back(t);
}
return s;
}
16. 判断两个二叉树是否互为镜像
bool isMirror(TreeNode* p, TreeNode* q){
if (p == NULL && q == NULL) return true;
if (p == NULL || q == NULL) return false;
if (p->val != q->val) return false;
return isMirror(p->left, q->right) && isMirror(p->right, q->left);
}
17. 判断一个二叉树本身是否为镜像二叉树(对称二叉树)
bool isMirrorTree(TreeNode* root){
return isMirror(root, root);//利用算法16,如果一个树是镜像的,那么它和自己本身互为镜像
}
18. 求两个节点最近的公共祖先
void help(TreeNode* p, map<TreeNode*, TreeNode*> &q){
if (p){
if (p->left) q[p->left] = p;
if (p->right) q[p->right] = p;
help(p->left, q);
help(p->right, q);
}
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
map<TreeNode*, TreeNode*> m;
TreeNode* head = root;
help(root, m);
if (m[p] == q) return q;
if (m[q] == p) return p;
while (p != head){
TreeNode* tmp = q;
while (tmp != head){
if (p == tmp || m[tmp] == p) return p;
if (m[p] == tmp) return tmp;
tmp = m[tmp];
}
p = m[p];
}
return head;
}
19. 判断两个节点是否为堂兄弟(深度相同且父节点不同)
void help(TreeNode *root, map<int, int> &p){
if (root != NULL){
if (root->left != NULL) p[root->left->val] = root->val;
if (root->right != NULL) p[root->right->val] = root->val;
help(root->left, p);
help(root->right, p);
}
}
map<int, int> p;
bool isCousins(TreeNode* root, int x, int y) {
help(root, p);
if (p[x] == 0 || p[y] == 0) return false;
if (p[x] == p[y]) return false;
int xi = 0, yi = 0;
while (p[x] != p[y]){
if (p[p[x]] != 0){
x = p[x];
xi++;
}
if (p[p[y]] != 0){
y = p[y];
yi++;
}
}
return xi == yi;
}
20.二叉树中的最大路径和
int dfs(TreeNode* root, int res){
if (!root) return 0;
int l = max(0, dfs(root->left, res));
int r = max(0, dfs(root->right, res));
res = max(l + r + root->val, res);
return root->val + max(l, r);
}
int maxSumPath(TreeNode* root){
int res = INT_MIN;
dfs(root, res);
return res;
}