【发布时间】:2023-04-02 15:11:01
【问题描述】:
编写函数T ComputeMedian() const 的实现,该函数在 O(n) 时间内计算树中的中值。假设这棵树是一个 BST,但不一定是平衡的。回想一下,n 个数字的中位数定义如下:如果 n 为奇数,则中位数为 x,使得小于 x 的值的数量等于大于 x 的值的数量。如果 n 是偶数,则一加小于 x 的值的数量等于大于 x 的值的数量。例如,给定数字 8、7、2、5、9,中位数为 7,因为有两个小于 7 的值和两个大于 7 的值。如果我们将数字 3 添加到集合中,则中位数变为 5。
这里是二叉搜索树节点的类:
template <class T>
class BSTNode
{
public:
BSTNode(T& val, BSTNode* left, BSTNode* right);
~BSTNode();
T GetVal();
BSTNode* GetLeft();
BSTNode* GetRight();
private:
T val;
BSTNode* left;
BSTNode* right;
BSTNode* parent; //ONLY INSERT IS READY TO UPDATE THIS MEMBER DATA
int depth, height;
friend class BST<T>;
};
二叉搜索树类:
template <class T>
class BST
{
public:
BST();
~BST();
bool Search(T& val);
bool Search(T& val, BSTNode<T>* node);
void Insert(T& val);
bool DeleteNode(T& val);
void BFT(void);
void PreorderDFT(void);
void PreorderDFT(BSTNode<T>* node);
void PostorderDFT(BSTNode<T>* node);
void InorderDFT(BSTNode<T>* node);
void ComputeNodeDepths(void);
void ComputeNodeHeights(void);
bool IsEmpty(void);
void Visit(BSTNode<T>* node);
void Clear(void);
private:
BSTNode<T> *root;
int depth;
int count;
BSTNode<T> *med; // I've added this member data.
void DelSingle(BSTNode<T>*& ptr);
void DelDoubleByCopying(BSTNode<T>* node);
void ComputeDepth(BSTNode<T>* node, BSTNode<T>* parent);
void ComputeHeight(BSTNode<T>* node);
void Clear(BSTNode<T>* node);
};
我知道我应该先计算树的节点,然后进行中序遍历,直到我到达第 (n/2) 个节点并返回它。我只是不知道怎么做。
【问题讨论】:
-
在列表的情况下,您必须在两端开始指针并向内工作以找到中位数。但是由于您的树不平衡,因此最坏的情况会简化为链表。因此,你不能避免做同样的事情。从最小值和最大值开始指针,并交替计算 inorder-successor(min) 和 inorder-predecessor(max) 直到它们相等。
-
@BadZen 我对“inorder-predecessor”不太熟悉..您能否进一步解释一下?
-
Next() 和 Prev() 树值。
标签: algorithm tree binary-search-tree median