ドライバープログラムと一緒に同じものの成功したコード実装は次のとおりです。
#include <iostream>
using namespace std;
class BinaryTree {
public:
BinaryTree *right;
BinaryTree *left;
int value;
BinaryTree(int value) {
this->value = value;
}
};
int max_value(int a, int b) {
if (a > b) {
return a;
} else {
return b;
}
}
int min_value(int a, int b) {
if (a < b) {
return a;
} else {
return b;
}
}
BinaryTree* findLargestBST(BinaryTree *n, int* maxSize, int *max, int *min, bool *is_bst) {
if (n == NULL) {
*maxSize = 0;
*is_bst = true;
return n;
}
int *lc_max_size = new int;
int *rc_max_size = new int;
int *lc_max = new int;
int *lc_min = new int;
int *rc_max = new int;
int *rc_min = new int;
*lc_max = std::numeric_limits<int>::min();
*rc_max = *lc_max;
*lc_min = std::numeric_limits<int>::max();
*rc_min = *lc_min;
BinaryTree* returnPointer;
bool is_curr_bst = true;
BinaryTree* lc = findLargestBST(n->left, lc_max_size, lc_max, lc_min, is_bst);
if (!*is_bst) {
is_curr_bst = false;
}
BinaryTree* rc = findLargestBST(n->right, rc_max_size, rc_max, rc_min, is_bst);
if (!*is_bst) {
is_curr_bst = false;
}
if (is_curr_bst && *lc_max <= n->value && n->value <= *rc_min) {
*is_bst = true;
*maxSize = 1 + *lc_max_size + *rc_max_size;
returnPointer = n;
*max = max_value (n->value, *rc_max);
*min = min_value (n->value, *lc_min);
} else {
*is_bst = false;
*maxSize = max_value(*lc_max_size, *rc_max_size);
if (*maxSize == *lc_max_size) {
returnPointer = lc;
} else {
returnPointer = rc;
}
*max = *min = n->value;
}
delete lc_max_size;
delete rc_max_size;
delete lc_max;
delete lc_min;
delete rc_max;
delete rc_min;
return returnPointer;
}
int main() {
/* Let us construct the following Tree
50
/ \
10 60
/ \ / \
5 20 55 70
/ / \
45 65 80
*/
BinaryTree *root = new BinaryTree(50);
root->left = new BinaryTree(10);
root->right = new BinaryTree(60);
root->left->left = new BinaryTree(5);
root->left->right = new BinaryTree(20);
root->right->left = new BinaryTree(55);
root->right->left->left = new BinaryTree(45);
root->right->right = new BinaryTree(70);
root->right->right->left = new BinaryTree(65);
root->right->right->right = new BinaryTree(80);
/* The complete tree is not BST as 45 is in right subtree of 50.
The following subtree is the largest BST
60
/ \
55 70
/ / \
5 65 80
*/
int *maxSize = new int;
int *min_value = new int;
int *max_value = new int;
*min_value = std::numeric_limits<int>::max();
*max_value = std::numeric_limits<int>::min();
bool *is_bst = new bool;
BinaryTree *largestBSTNode = findLargestBST(root, maxSize, max_value, min_value, is_bst);
printf(" Size of the largest BST is %d", *maxSize);
printf("Max size node is %d", largestBSTNode->value);
delete maxSize;
delete min_value;
delete max_value;
delete is_bst;
getchar();
return 0;
}
使用されるアプローチはかなり単純で、次のように理解できます。
これは、ツリーがBSTであるかどうかを判断するときに使用する上から下へのアプローチではなく、下から上へのアプローチです。これは、ツリーをBSTとして決定するときに使用されるのと同じmax-minアプローチを使用します。
以下は、各ノードで再帰的に実行されるステップです。
注:これはボトムアップのアプローチであり、情報は下から上に流れることに注意してください。
1)私が存在するかどうかを判断します。私がそうでない場合(私はnullです)、アルゴリズムに影響を与えてはならず、変更を加えずに戻る必要があります。
2)すべてのノードで、この時点までのBSTの最大サイズが格納されます。これは、この特定のノードのツリーがBSTプロパティを満たしている場合、左側のサブツリーの合計サイズ+右側のサブツリーの合計サイズ+ 1(ノード自体の場合)を使用して決定されます。それ以外の場合は、左側のサブツリーと右側のサブツリーから返された最大値から計算されます。
3)指定されたノードでBSTプロパティが満たされている場合、現在のノードはこの時点までの最大サイズBSTとして返されます。それ以外の場合は、左右のサブツリーから決定されます。