13template <
class T,
class Comparator>
14class DiscretePDF<T, Comparator>::Node
20 Node *parent, *left, *right;
28 Node *sibling() {
return this==parent->left?parent->right:parent->left; }
30 void markRed() { m_mark =
true; }
31 void markBlack() { m_mark =
false; }
32 bool isBlack() {
return !m_mark; }
33 bool leftIsBlack() {
return !left || left->isBlack(); }
34 bool rightIsBlack() {
return !right || right->isBlack(); }
37 if (left) sumWeights += left->sumWeights;
38 if (right) sumWeights += right->sumWeights;
44template <
class T,
class Comparator>
45DiscretePDF<T, Comparator>::Node::Node(T key_, weight_type weight_, Node *parent_) {
55template <
class T,
class Comparator>
56DiscretePDF<T, Comparator>::Node::~Node() {
63template <
class T,
class Comparator>
68template <
class T,
class Comparator>
73template <
class T,
class Comparator>
78template <
class T,
class Comparator>
84 if (!n->leftIsBlack() && !n->rightIsBlack())
89 assert(0 &&
"insert: argument(item) already in tree");
91 n = lessThan(item, n->key) ? n->left : n->right;
95 n =
new Node(item, weight, p);
100 if (lessThan(item, p->key)) {
112template <
class T,
class Comparator>
114 Node **np = lookup(item, 0);
115 Node *child, *n = *np;
118 assert(0 &&
"remove: argument(item) not in tree");
121 Node **leftMaxp = &n->left;
123 while ((*leftMaxp)->right)
124 leftMaxp = &(*leftMaxp)->right;
126 n->key = (*leftMaxp)->key;
127 n->weight = (*leftMaxp)->weight;
135 child = n->left?n->left:n->right;
139 child->parent = n->parent;
146 propagateSumsUp(n->parent);
148 n->left = n->right = 0;
153template <
class T,
class Comparator>
155 Node *n = *lookup(item, 0);
158 assert(0 &&
"update: argument(item) not in tree");
165template <
class T,
class Comparator>
167 assert (!((p < 0.0) || (p >= 1.0)) &&
"choose: argument(p) outside valid range");
170 assert(0 &&
"choose: choose() called on empty tree");
172 weight_type w = (weight_type) (m_root->sumWeights * p);
177 if (w<n->left->sumWeights) {
181 w -= n->left->sumWeights;
184 if (w<n->weight || !n->right) {
194template <
class T,
class Comparator>
196 Node *n = *lookup(item, 0);
201template <
class T,
class Comparator>
203 Node *n = *lookup(item, 0);
210template <
class T,
class Comparator>
211typename DiscretePDF<T, Comparator>::Node **
214 Node *n, *p=0, **np=&m_root;
221 if (lessThan(item, n->key)) {
234template <
class T,
class Comparator>
236 if (n->left) n->left->markBlack();
237 if (n->right) n->right->markBlack();
245 p->parent->markRed();
248 if (!((n==p->left && p==p->parent->left) ||
249 (n==p->right && p==p->parent->right))) {
260template <
class T,
class Comparator>
262 Node *p=n->parent, *pp=p->parent;
270 if (p->left) p->left->parent = p;
274 if (p->right) p->right->parent = p;
291template <
class T,
class Comparator>
295 }
else if (n->parent) {
296 Node *sibling = n->sibling();
298 if (sibling && !sibling->isBlack()) {
299 n->parent->markRed();
300 sibling->markBlack();
303 sibling = n->sibling();
310 }
else if (sibling->leftIsBlack() && sibling->rightIsBlack()) {
311 if (n->parent->isBlack()) {
316 n->parent->markBlack();
319 if (n==n->parent->left && sibling->rightIsBlack()) {
320 rotate(sibling->left);
322 sibling->parent->markBlack();
323 sibling = sibling->parent;
324 }
else if (n==n->parent->right && sibling->leftIsBlack()) {
325 rotate(sibling->right);
327 sibling->parent->markBlack();
328 sibling = sibling->parent;
334 if (!n->parent->isBlack())
336 sibling->left->markBlack();
337 sibling->right->markBlack();
342template <
class T,
class Comparator>
344 for (; n; n=n->parent)
void insert(T item, weight_type weight)
void update(T item, weight_type newWeight)
void lengthen(Node *node)
weight_type getWeight(T item)
void propagateSumsUp(Node *n)
Node ** lookup(T item, Node **parent_out)