我有一个二叉搜索树( BST )。在这种情况下我需要打印它的值:min,max,second min,second max ...
例如:如果树包含值1,2,3,4,5,6,7
,则应打印:1,7,2,6,3,5,4
。我无法更改树,或使用其他数据结构,如set或list。我还需要在 O(nlogn)中完成。
BST 的节点用struct:
表示struct nodeT{
int value;
nodeT * left;
nodeT * right;
};
void PrintTree(nodeT * head){
}
答案 0 :(得分:1)
对于最小值,您可以使用递归查找等于或大于另一个值的值的函数。你首先用例如INT_MIN
这意味着它将在树中找到最低值。然后使用找到的值,添加一个,再次调用相同的函数,这将找到第二个最小的值,等等。
对于最大值,请使用相同的基本算法,但检查等于或小于,并以INT_MAX
开头。
当前"最小"找到的值大于当前最大的"价值,然后你互相传递并结束搜索。
注1: 这适用于整数值,浮点值可能不太好。
注2: 我没有考虑过大O,这只是我想到的最重要的事情。
在伪代码中:
print_smallest_and_largest()
{
int current_smallest = INT_MIN;
int current_largest = INT_MAX;
// Infinite loop
for (;;)
{
current_smallest = find_equal_or_bigger_than(current_smallest);
current_largest = find_equal_or_smaller_than(current_largest);
if (current_smallest > current_largest)
break; // Got all values
printf("Smallest: %d\n", current_smallest);
printf("Largest: %d\n", current_largest);
++current_smallest;
--current_largest;
}
}
答案 1 :(得分:0)
在BST中,节点的左子树仅包含键小于节点键的节点。并且节点的右子树仅包含键大于节点键的节点。因此,在构建BST之后,您应该注意到 - 最小元素应该在最左边的节点中,最大元素应该在最右边的节点中。
所以你可以通过遍历最左边或最右边的树来检索O(log n)时间内的最小/最大元素:
struct treeNode {
treeNode* left;
treeNode* right;
int key;
}*root;
template <class Object>
treeNode* BinarySearchTree <Object> :: minHelper(treeNode* &node) {
if(node -> left == NULL) return node;
else minHelper(node -> left);
}
template <class Object>
treeNode* BinarySearchTree <Object> :: min() {
return minHelper(root);
}
template <class Object>
treeNode* BinarySearchTree <Object> :: maxHelper(treeNode* &node) {
if(node -> right == NULL) return node;
else maxHelper(node -> right);
}
template <class Object>
treeNode* BinarySearchTree <Object> :: max() {
return maxHelper(root);
}
编写了一个完整的程序
答案 2 :(得分:0)
最小值为:
如果根没有左子,那么根。否则是最左边的节点,这样没有right
的节点从根到自身分支。
最大值为:如果root没有正确的子项,则为root。否则最右边的节点没有从根到自身的左分支。
你可以在平均情况下使用lg(N)操作找到这两个
所以完整的算法变为:
运行时分析:根据定义,删除BST中的节点平均需要lg(N)时间,我们之前已经显示,找到最大值或最小值也需要lg(N)时间(平均情况下)。所以运行时平均为O(NlgN)。
答案 3 :(得分:0)
对其他数据结构的限制是纯粹的教学法(如果是的话,那就好了)?如果你可以使用另一种数据结构,它会使事情变得更简单。如果它不明显,这里有一种方法在O(N)时间(但O(N)空间)
其他答案概述了另一种递归方式。