1,恢复二叉树
题目分析:给定一颗二叉搜索树,有两个节点错误的交换了值,现在去将这两个值重新交换回来。
解题思路:
根据二叉搜索树的性质,选择中序遍历的方法,可得到顺序的序列。
情况一:两个错误的节点是直接相连的,情况二:两个错误的节点不是直接相连的
在下面的递归过程中,在进入下次递归前都会保存当前节点,为了同下次递归的节点进行比较。
不管哪种情况,当上一个节点的值大于当前节点的值时,
第一次找到的错误节点肯定是当前节点的上一个节点, 第二个错误节点肯定是当前节点。
//恢复二叉树
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
TreeNode* per = NULL; //为保存上次节点,,和下面两个一样是全类变量
TreeNode* n1 = NULL;
TreeNode* n2 = NULL;
void recoverTree(TreeNode *root) {
if (root == NULL)
return;
_recoverTree(root);
if (n1 != NULL && n2 != NULL) //找到直接交换
{
int tmp = n1->val;
n1->val = n2->val;
n2->val = tmp;
}
}
void _recoverTree(TreeNode* root) //中序遍历的方式
{
if (root == NULL)
return;
_recoverTree(root->left);
if (per != NULL && per->val > root->val)
{
if (n1 == NULL)
n1 = per; //第一次找到肯定是per
n2 = root; //第二次找到肯定是root ,第一次就给n2赋值,解决了两个错误节点相连的问题
}
per = root; //为下次递归保存节点
_recoverTree(root->right);
}
};
2,检测搜索二叉树
题目分析:一颗搜索二叉树必定满足,其中任意一个节点的值都比他的左子树的值大,比他的右子树的值小的规则。
思路分析:采用中序遍历的方式,去检测。检测的方式就是,用当前节点和上一个节点进行比较。不满足就直接返回。
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
bool isValidBST(TreeNode* root) {
TreeNode* per = NULL; //传指针的方式保存上一个节点。
return _isValidBST(root, per);
}
bool _isValidBST(TreeNode* root, TreeNode*& per)
{
if (root == NULL)
return true;
if (!_isValidBST(root->left, per)) return false;
if (per != NULL && per->val > root->val) return false; //这是返回错误的起点,递归返回,不再进入其他节点
per = root;//保存前节点
return _isValidBST(root->right, per);
}
};