Напишите реализацию функции 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>;
};
Binary класс дерево поиска:
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
@BadZen Я не совсем знаком с «inorder-предшественником» .. Не могли бы вы, пожалуйста, объяснить еще? –
Следующие() и Prev() значения дерева. – BadZen