node *_balance(int n, int *a) { int nl, nr; node *p; if (n > 0) { nl = (n-1) / 2; nr = n - nl - 1; p = (node*)malloc(sizeof(node)); p->left = _balance(nl, a); p->key = a[_index++]; p->right = _balance(nr, a); return p; } else return NULL; }
node *_balance(int n, void *a, size_t width) { int nl, nr; node *p; if (n > 0) { nl = (n-1) / 2; nr = n - nl - 1; p = (node*)malloc(sizeof(node) + width); p->left = _balance(nl, a, width); memcpy(p+1, (char*)a+(_index++)*width, width); p->right = _balance(nr, a, width); return p; } else return NULL; }
void PhotonMap::_balance(Photon **pbal, Photon **porg, unsigned index, unsigned start, unsigned end, AABB &aabb) { const unsigned last = end - start + 1; unsigned median = 1; while ((median * 4) <= last) median += median; if ((3 * median) <= last) { median += median; median += start - 1; } else { median = end - median + 1; } const unsigned axis = aabb.getMaxExtent(); assert(axis >= 0 && axis <3); _median_split(porg, start, end, median, axis); pbal[index] = porg[median]; pbal[index]->plane = axis; if (median > start) { if (start < median - 1) { const real_t tmp = aabb.max[axis]; aabb.max[axis] = pbal[index]->position[axis]; _balance(pbal, porg, 2 * index, start, median - 1, aabb); aabb.max[axis] = tmp; } else { pbal[2 * index] = porg[start]; } } if (median < end) { if (median + 1 < end) { const real_t tmp = aabb.min[axis]; aabb.min[axis] = pbal[index]->position[axis]; _balance(pbal, porg, 2 * index + 1, median + 1, end, aabb); aabb.min[axis] = tmp; } else { pbal[2 * index + 1] = porg[end]; } } }
void PhotonMap::init() { // build the underlying balanced kd-Tree if (size() > 1) { Photon **orig = (Photon **) malloc(sizeof(Photon*) * (size() + 1)); Photon **tree = (Photon **) malloc(sizeof(Photon*) * (size() + 1)); AABB aabb; // add all photons for (unsigned i = 1; i <= size(); ++i) { orig[i] = &m_photons[i]; m_photons[i].plane = 0; aabb.add(m_photons[i].position); tree[i] = NULL; } // recursively balance tree _balance(tree, orig, 1, 1, size(), aabb); free(orig); unsigned d, j = 1, temp = 1; Photon temp_photon = m_photons[j]; // update internal bookkeeping for (unsigned i = 1; i <= size(); ++i) { d = tree[j] - &m_photons[0]; tree[j] = NULL; if (d != temp) { m_photons[j] = m_photons[d]; } else { m_photons[j] = temp_photon; if (i < size()) { for (; temp <= size(); ++temp) if (tree[temp] != NULL) break; temp_photon = m_photons[temp]; j = temp; } continue; } j = d; } free(tree); } m_halfPhotons = m_size / 2 - 1; }
struct AVLNode *_removeLeftmost(struct AVLNode *cur) { struct AVLNode *temp; if(cur->left != 0) { cur->left = _removeLeftmost(cur->left); return _balance(cur); } temp = cur->rght; free(cur); return temp; }
void bti_balance(node *base, size_t *num) { int *tmp; int ntmp = *num; tmp = (int*)malloc(sizeof(int)*(ntmp)); _index = 0; _sort(base->left, tmp); ntmp = *num; bti_deleteall(base, num); _index = 0; base->left = _balance(ntmp, tmp); *num = ntmp; free(tmp); }
void btv_balance(node *base, size_t *num, size_t width) { void *tmp; int ntmp = *num; tmp = malloc(width*ntmp); _index = 0; _sort(base->left, tmp, width); ntmp = *num; btv_deleteall(base, num); _index = 0; base->left = _balance(ntmp, tmp, width); *num = ntmp; free(tmp); }
struct AVLNode *_addNode(struct AVLNode *cur, void * val, comparator compare) { struct AVLNode *newNode; if(cur == 0) /* Base Case */ { /* Create a new one and return it */ newNode = (struct AVLNode *)malloc(sizeof(struct AVLNode)); assert(newNode != 0); newNode->left = newNode->rght = 0; newNode->val = val; newNode->hght = 0; /* or SetHeight on new Node */ return newNode; /* No need to balance here! */ } else { /* recursive case */ if((*compare)(val, cur->val) < 0) cur->left = _addNode(cur->left, val, compare); /* functional approach, rebuild subtree */ else cur->rght = _addNode(cur->rght, val, compare); } /* must balance the tree on way up from the recursion */ return _balance(cur); /* return the 'rebuilt' tree as come back from recursion */ }
struct AVLNode *_removeNode(struct AVLNode *cur, void * val, comparator compare) { struct AVLNode *temp; if((*compare)(val, cur->val) == 0) { if(cur->rght != 0) { cur->val = _leftMost(cur->rght); cur->rght =_removeLeftmost(cur->rght); /* return _balance(cur);*/ /* could remove this since there's a return at the end*/ } else { temp = cur->left; free(cur); return temp; } } else if((*compare)(val, cur->val) < 0) cur->left = _removeNode(cur->left, val, compare); else cur->rght = _removeNode(cur->rght, val, compare); return _balance(cur); }