Recover Binary Search Tree 复原二叉搜索树
题目描述:
Two elements of a binary search tree (BST) are swapped by mistake.
Recover the tree without changing its structure.
Note:
A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?
confused what "{1,#,2,3}"
means? > read more on how binary tree is serialized on OJ.
思路:
二叉搜索树的概念:二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。现在我们来用下面的树分析:
4
/ \
2 6
/ \ / \
1 5 3 7
正确的中序遍历为:左根右的原则:[1234567]
现在的中序遍历为:[1254367]
很明显3和5颠倒了。那么在中序遍历时:当碰到第一个逆序时:为5->4,那么将first指向5,second指向4,注意,此时first已经确定下来了。然后pre和root一直向后遍历,直到碰到第二个逆序时:4->3,此时将second指向3,那么first和second都已经确定,只需要交换节点的值即可。prev指针用来比较中序遍历中相邻两个值的大小关系,很巧妙。
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*//*
4
/ \
2 6
/ \ / \
1 5 3 7
正确的中序遍历为:左根右的原则:[1234567]
现在的中序遍历为:[1254367]
很明显3和5颠倒了。那么在中序遍历时:当碰到第一个逆序时:为5->4,那么将first指向5,second指向4,
注意,此时first已经确定下来了。然后parent和root一直向后遍历,直到碰到第二个逆序时:4->3,此时将second指向3,
那么first和second都已经确定,只需要交换节点的值即可。pre指针用来比较中序遍历中相邻两个值的大小关系*/
class Solution {
public:
//非递归
/*void recoverTree(TreeNode *root) {
TreeNode *first = NULL, *second = NULL, *parent = NULL;
TreeNode *cur, *pre;
cur = root;
while (cur) {
if (cur->left==NULL) {
if (parent && parent->val > cur->val) {
if (!first) first = parent;
second = cur;
}
parent = cur;
cur = cur->right;
} else {
pre = cur->left;
while (pre->right && pre->right != cur) pre = pre->right;
if (!pre->right) {
pre->right = cur;
cur = cur->left;
} else {
pre->right = NULL;
if (parent->val > cur->val) {
if (!first) first = parent;
second = cur;
}
parent = cur;
cur = cur->right;
}
}
}
if (first && second) swap(first->val, second->val);*/
//递归
//定义三个指针,*pre用来比较大小,*first用来存放第一个错位的数,*second用来存放第二个错位的数
TreeNode *pre;
TreeNode *first;
TreeNode *second;
void recoverTree(TreeNode *root) {
pre = NULL;
first = NULL;
second = NULL;
inorder(root);
if (first !=NULL&& second!=NULL) //交换两个错位的值
swap(first->val, second->val);
}
void inorder(TreeNode *root) {
if (root==NULL)
return;
inorder(root->left);//递归遍历左子树
if (pre==NULL)
pre = root;
else {
if (pre->val > root->val) {
if (first==NULL)
first = pre;
second = root;
}
pre = root;
}
inorder(root->right);//递归遍历右子树
}
};