题目
一个升序的二叉树里,其中有两个结点的数据被误交换了,现需要找出这个两结点,交换回来
结论
注意,数组表示的二叉树,顶层从0开始,其中结点里的零表示空结点,n层从 2n 开始,像【1,3, 0, 0,2】,顶层是1, 第二层是3, 0,第三层左到右,0, 2, 0, 0
before:
lst: 1 3 0 0 2
tree: 0 3 2 1 0
result
lst: 3 1 0 0 2
tree: 0 1 2 3 0
before:
lst: 3 1 4 0 0 2
tree: 0 1 0 3 2 4
result
lst: 2 1 4 0 0 3
tree: 0 1 0 2 3 4
代码
其实只要按正常的遍历(左结点,中,右结点)顺序,找出两个不按顺序的结点的即可
#include <iostream>
#include <vector>
class RecoverTree {
public:
RecoverTree(int* data, int count) {
tree_data.resize(count);
for (int i = 0; i < count; ++i) tree_data[i] = data[i];
}
~RecoverTree() {
}
void __d_recover_tree(std::vector<int>& tree, int p_index) {
if (p_index >= tree.size() || tree[p_index] == 0)
return;
int left_index = p_index * 2 + 1;
int right_index = p_index * 2 + 2;
__d_recover_tree(tree, left_index);
if (cur_tree_index == -1) {
cur_tree_index = p_index;
}
else {
int a = tree[cur_tree_index];
int b = tree[p_index];
if (tree[cur_tree_index] != 0 && a > b) {
if (this->first_diff == this->last_diff) {
this->first_diff = cur_tree_index;
this->last_diff = p_index;
}
else {
this->last_diff = p_index;
}
}
else {
do_switch();
}
}
cur_tree_index = p_index;
__d_recover_tree(tree, right_index);
}
void do_switch() {
if (first_diff != last_diff) {
int t = tree_data[last_diff];
tree_data[last_diff] = tree_data[first_diff];
tree_data[first_diff] = t;
first_diff = last_diff = 0;
}
}
void _output_tree(const std::vector<int>& tree, int p_index) {
if (p_index >= tree.size())
return;
int left_index = p_index * 2 + 1;
int right_index = p_index * 2 + 2;
_output_tree(tree, left_index);
std::cout << " " << tree[p_index];
_output_tree(tree, right_index);
}
void output_tree() {
std::cout << std::endl << "lst:";
for (auto t : this->tree_data) std::cout << " " << t;
std::cout << std:: endl << "tree:";
_output_tree(this->tree_data, 0);
}
void _recover_tree() {
// O(n) 的话,这得要求一次遍历就能把对应的位置找到
// count = 2^c (c为层数
// 求层数
cur_tree_index = -1;
first_diff = last_diff = 0;
__d_recover_tree(tree_data, 0);
do_switch();
}
protected:
int cur_tree_index = 0;
int first_diff = 0;
int last_diff = 0;
std::vector<int> tree_data;
};
void recover_tree() {
if(true){
int tree[] = { 1,3,0, 0, 2 };
//
int count = sizeof(tree) / sizeof(int);
RecoverTree t(tree, count);
std::cout << std::endl << "before:";// << std::endl;
t.output_tree();
t._recover_tree();
std::cout << std::endl << "result" << std::endl;
t.output_tree();
}
{
int tree[] = { 3,1, 4,0, 0, 2 };
int count = sizeof(tree) / sizeof(int);
RecoverTree t(tree, count);
std::cout << std::endl << "before:";
t.output_tree();
t._recover_tree();
std::cout << std::endl << "result";
t.output_tree();
}
}