常见题
二叉树这里主要是二叉树的递归套路
二叉树有一个潜台词:
给定头节点,左树和右树可以返回信息
寻找直接后继
意思是,给定二叉树中随机一个节点(这个节点包含指向其父树的指针),找到其在中序遍历中的下一个节点
解法1:暴力遍历
既然有指针,就根据一个节点找到整棵树,在做一遍中序遍历
coding
struct TreeNode{
int value;
struct TreeNode* left;
struct TreeNode* right;
struct TreeNode* parent;
};
struct TreeNode* whole(struct TreeNode* node){
if(node ==NULL){
return NULL;
}
struct TreeNode* p = (struct TreeNode*)malloc(sizeof(struct TreeNode));
p = node;
if(p->parent != NULL){
p = p->parent;
}
return p;
}
struct TreeNode* find(struct TreeNode* node){
if(struct TreeNode* node == NULL){
return NULL;
}
struct TreeNode* head = (struct TreeNode*)malloc(sizeof(struct TreeNode));
head = whole(node); // 现在是头指针辣
// 中序遍历
find(head->left);
printf("%d ", head->value);
find(head->right);
....
// 倒进数组...找下标...
解法2:找规律,再递归
![](https://i-blog.csdnimg.cn/blog_migrate/c7cceaca2d8765ec13a8d70ac6650606.jpeg)
如图,两种情况
coding试试
struct TreeNode{
int value;
struct TreeNode* left;
struct TreeNode* right;
struct TreeNode* parent;
};
struct TreeNode* getLeftMost(struct TreeNode* node){
if(node ==NULL){
return node;
}
while(node->left !=NULL){ // 只要有左子树 就一直往上
node = node->left;
}
return node;
}
struct TreeNode* get(struct TreeNode* node){
if(node==NULL){
return node;
}
if(node->right != NULL){
return getLeftMost(node->right); // 一直往上找
}
else{
struct TreeNode* next = (struct TreeNode*)malloc(sizeof(struct TreeNode));
next = node->parent;
while(parent!= NULL && parent->left != node/*parent->right == node*/){
next = parent;
parent = node->parent;
}
return parent;
}
}
判断是否平衡二叉树
平衡:左子树和右子树的高度差不超过1
所以要满足
左树平衡 右树平衡
左右高度差不超过1
所以这道题对左右树的要求相同:
需要两个信息 1. 是否平衡 2. 树高度
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
// 二叉树结点的定义
struct TreeNode {
int val;
TreeNode *left, *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
// 返回给定节点为根节点的二叉树的高度
int getHeight(TreeNode* root) {
if (root == NULL) {
return 0;
}
return max(getHeight(root->left), getHeight(root->right)) + 1;
}
// 判断给定节点为根节点的二叉树是否为平衡二叉树
bool isBalanced(TreeNode* root) {
if (root == NULL) {
return true;
}
int leftHeight = getHeight(root->left);
int rightHeight = getHeight(root->right);
if (abs(leftHeight - rightHeight) > 1) {
return false;
} else {
return isBalanced(root->left) && isBalanced(root->right);
}
}
判断是否搜索二叉树
题目:返回满足搜索二叉树的头节点
特点:每一颗子树 左树都比root小,右树都比root大(感觉好像小根堆)
思路:
既然要判断是不是左树大于根、右树大于根。而左右树又不需要比较...
就是说 左比根 右比根
#include<iostream>
using namespace std;
// 二叉树结点的定义
struct TreeNode {
int val;
TreeNode *left, *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
// 用于记录最大BST的信息
struct BSTInfo {
bool isBST; // 是否是BST
int minVal; // 最小值
int maxVal; // 最大值
TreeNode *root; // BST的根节点
int size; // BST的节点数
};
// 递归函数,返回以root为根节点的BST的信息
BSTInfo getBSTInfo(TreeNode* root) {
if (root == NULL) {
return { true, INT_MAX, INT_MIN, NULL, 0 };
}
BSTInfo left = getBSTInfo(root->left);
BSTInfo right = getBSTInfo(root->right);
if (left.isBST && right.isBST && left.maxVal < root->val && root->val < right.minVal) {
// 以root为根节点的树是BST
return { true, min(left.minVal, root->val), max(right.maxVal, root->val), root, left.size + right.size + 1 };
} else {
// 以root为根节点的树不是BST
// 返回左右子树中最大的BST
if (left.size > right.size) {
return left;
} else {
return right;
}
}
}
// 返回给定二叉树中最大的BST的头节点
TreeNode* getMaxBST(TreeNode* root) {
return getBSTInfo(root).root;
}
总结
递归套路真的不太容易...
有思路容易
理解难
coding更难...
多画点脑图,一步一步拆解去理解可能更方便一些..