计算二叉搜索树中的中位数

时间:2014-01-26 13:33:23

标签: c++ binary-search-tree median

编写函数ComputeMedian的实现,该函数在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);

};

我尝试编写此函数:我添加了两个新成员数据BSTNode<T>* medint count,只有当项目数为奇数时,此函数才会计算中位数:

template <class T>
T BST<T>::ComputeMedian()
{
BSTNode<T> *median;
int numOfNodes = CountNodes();
if (numOfNodes % 2 != 0) {
    count = 0;
    ComputeOddMedian(root, numOfNodes/2);
    median = med;
    return median->val;

    }
else {
    count = 0;
    ComputeEvenMedian(root, numOfNodes/2);
    median = med;
    return median->val;

    }
return -1;
}

template <class T>
void BST<T>::ComputeOddMedian(BSTNode<T> *node, int x)
{
if (node->left) ComputeOddMedian(node->left, x);
count++;
if (count == x+1)
    med = node;
if (node->right) ComputeOddMedian(node->right, x);
}

template <class T>
void BST<T>::ComputeEvenMedian(BSTNode<T> *node, int x)
{
if (node->left) ComputeOddMedian(node->left, x);
count++;
if (count == x-1)
    med = node;
if (node->right) ComputeOddMedian(node->right, x);
}

当项目数为奇数时,它会给出正确的结果,但当项目数为偶数时会导致错误(我认为这是因为可能存在NULL指针)。我觉得我的实现有问题,特别是在递归函数中使用return并添加了新的成员数据。

编辑: 对于奇数项目:

int main()
{
BST<int> tree;
int x=12;
tree.Insert(x);
x=6;
tree.Insert(x);
x=22;
tree.Insert(x);
x=3;
tree.Insert(x);
x=10;
tree.Insert(x);
cout << tree.ComputeMedian() << endl;
}

对于上面的代码,输出为10,这是真的。

对于偶数项目:

int main()
{
BST<int> tree;
int x=12;
tree.Insert(x);
x=6;
tree.Insert(x);
x=22;
tree.Insert(x);
x=3;
tree.Insert(x);
x=10;
tree.Insert(x);
x=17;
tree.Insert(x);
cout << tree.ComputeMedian() << endl;
}

对于上面的代码,没有输出,这是错误的屏幕截图:

Screenshot

0 个答案:

没有答案