给定BST(二进制搜索树),如何计算O(log N)中比给定节点更小/更大的节点数。 假设您可以修改节点以向其中添加更多变量,并且在构建树时,只要它们小于O(n ^ 2)就可以执行操作。
此外,它还有助于提供图片以显示应考虑哪些子树。
答案 0 :(得分:2)
这是增强搜索树的经典用法。基本上,您通过为每个节点添加父指针来增加BST,以及每个节点下的子节点总数(在构建树时可以执行此操作,而无需额外的渐近成本)。
要解决此问题,请计算给定节点左子树下的子节点总数(常数时间,因为您只需在增强树数据中查找)。然后,将父指针移向根。在每个父级,如果您来自正确的子树,请将左子树子计数添加到总计数中。
因为你的树是平衡的,所以当你走到根时,你只会做O(log n)工作。
答案 1 :(得分:0)
如果您可以存储每个节点的子树权重,则可以在(log n)中进行(一次搜索目标)。
搜索您的目标并计算权重,
class node{
public:
int value;
node* left;
node* right;
int leftWeight;
int rightWeight;
node(int value, node* left, node* right, int leftWeight, int rightWeight){
this->value = value;
this->left = left;
this->right = right;
this->leftWeight = leftWeight;
this->rightWeight = rightWeight;
}
};
void search_tree(node* root, int key){
bool found = false;
node* tmp = root;
int greaterCount, smallerCount;
greaterCount = smallerCount = 0;
while (!found && tmp != nullptr){
if (key < tmp->value){
// +1 for tmp it self
greaterCount += tmp->rightWeight + 1;
tmp = tmp->left;
}
else if (key > tmp->value){
// +1 for tmp it self
smallerCount += tmp->leftWeight + 1;
tmp = tmp->right;
}
else {
// found
found = true;
smallerCount += tmp->leftWeight;
greaterCount += tmp->rightWeight;
}
}
// If element isn't found , you can delete this
if (!found){
cout << "targer not found" << endl;
return;
}
cout << "Elements greater than " << key << ": " << greaterCount << endl
<< "Elements smaller than " << key << ": " << smallerCount << endl;
}
int main() {
/*
Tree
.....................(10)........................
.................../.....\.......................
.................(5).....(20)....................
.............../...\..../....\...................
.............(4)..(8)..(11)...(40)...............
............/.............\......................
...........(1)............(12)....................
*/
//Left subtree
node* n1 = new node(1, nullptr, nullptr, 0, 0);
node* n4 = new node(4, n1, nullptr, 1, 0);
node* n8 = new node(8, nullptr, nullptr, 0, 0);
node* n5 = new node(5, n4, n8, 2, 1);
//Right subtree
node* n12 = new node(12, nullptr, nullptr, 0, 0);
node* n11 = new node(11, nullptr, n12, 0, 1);
node* n40 = new node(40, nullptr, nullptr, 0, 0);
node* n20 = new node(20, n11, n40, 2, 1);
// Root
node* n10 = new node(10, n5, n20, 4, 4);
search_tree(n10, 12);
return 0;
}
我假设已经创建了树(您可以在插入节点时更新权重), 每当你进入节点并且它不是你的目标,检查它是否比你的目标更重要或更小 如果它更大,则此节点的右子树也将比目标更大,然后更新greaterCount 如果节点小于目标,则使用左子树进行相同的操作。