Two elements of a binary search tree (BST) are swapped by mistake.
Recover the tree without changing its structure.
Recover the tree without changing its structure.
Note: AsolutionusingO(n)spaceisprettystraightforward. Couldyoudeviseaconstantspacesolution?
思路:
二叉搜索树的中序遍历,是一个按值从小到大排列的,如1234567.
O(n)的方法简单,就是生成中序遍历的数组,重新排序,然后重新生成二叉查找树。
常数空间复杂度,我们只需要保存那两个错误的节点,调换即可。
比如:
1234567,其中4和6错位了,变成了1236547。发现规律了没?6是第一个大于后面的数,而4则是最后一个小于前面的数。我们只要找出这两个数,调换即可。
#include <iostream>
using namespace std;
struct TreeNode{
int data;
TreeNode *left;
TreeNode *right;
TreeNode(int x):data(x),left(NULL),right(NULL){}
};
class Solution{
private:
TreeNode *node1,*node2;
TreeNode *pre;
void traverse(TreeNode *root)
{
if(root == NULL) return;
traverse(root->left);
if(pre!=NULL && pre->data > root->data)
{
node2 = root;//记录最后一次小于前面的root
if(node1 == NULL)//记录第一次大于后面时的pre
{
node1 = pre;
}
}
pre = root;
traverse(root->right);
}
public:
void recoverTree(TreeNode *root)
{
node1 = node2 = NULL;
pre = NULL;
traverse(root);
int tmp = node1->data;
node1->data = node2->data;
node2->data = tmp;
}
};
//创建一个二叉树
void buildTree2(TreeNode **T)
{
int ch;
cin>>ch;
if(ch == 0)
{
*T = NULL;
}
else
{
*T = new TreeNode(ch);
printf("请输入%d的左孩子:",ch);
buildTree2(&((*T)->left));
printf("请输入%d的右孩子:",ch);
buildTree2(&((*T)->right));
}
}
//中序遍历
void midTraverse(TreeNode *root)
{
if(root == NULL) return;
midTraverse(root->left);
printf("%d ",root->data);
midTraverse(root->right);
}
void main()
{
TreeNode *T;
buildTree2(&T);//创建一个1236547
midTraverse(T);
printf("\n");
Solution *sol = new Solution;
sol->recoverTree(T);//恢复成1234567
midTraverse(T);
printf("\n");
delete sol;
}