BNode* Trie :: Optimize(BNode* root) { if(root == NULL) return NULL; if(root->l == NULL && root->r == NULL) { return root; } BNode *l = Optimize(root->l); BNode *r = Optimize(root->r); if(l == NULL || r== NULL) { if(l == NULL) { if(isLeafNode(r)) { return r; } } else { if(isLeafNode(l)) { return l; } } } if(isLeafNode(l) && isLeafNode(r)) { int leftData = ((TNode*)l)->data; int rightData = ((TNode*)r)->data; if(leftData == rightData) { //When we arrived at tha Leaf Node and both the leaf nodes have same Neaxt Hop then we do trie shrinking return r; } } root->l = l; root->r = r; return root; }
TrieResult Trie :: Search(string destIp) { TrieResult res; string prefixIp = ""; BNode *tPtr = head; int currLevel = 0; while(1) { if(tPtr == NULL) break; if(isLeafNode(tPtr)) { res.IpPrefix = prefixIp; res.nextHop = ((TNode *)tPtr)->data; break; } if(destIp[currLevel] == '0') { //When the current level bit is 0 then we add 0 bit in the prefix result prefixIp += '0'; tPtr = tPtr->l; currLevel++; } else { prefixIp += '1'; //When the current level bit is 1 then we add 1 1 in the prefix result tPtr = tPtr->r; currLevel++; } } return res; }
int removeWord (trieNode **root, char *word) { if (*word == '\0') { (*root)->isleaf = false; if ( isLeafNode(*root) ) return 1; else return 0; } for (int i = 0; i < ALPHABET_SIZE; i++) { int index = char2ascii(*word); if ((*root)->next[index]) { if (removeWord((*root)->next[index], word + 1)) { removeNode((*root)->next[index]); return 1; } break; } } return 0; }
void Octree::insert(Entity *entity, MemoryArena *memArena) { if(isLeafNode()) { uint32 hashIndex = entityHashFunction(entity); entity_reference *existingReference = entityReferenceBlock->entityReferences + hashIndex; if(existingReference->index == 0) { existingReference->index = entity->entityID; entityReferenceBlock->entityCount++; } else { // External chaining while(existingReference->next) { existingReference = existingReference->next; } existingReference->next = PushStruct(memArena, entity_reference); existingReference->next->index = entity->entityID; existingReference->next->next = 0; } } else { insertToCollidedChildren(entity, memArena); } entityCount++; }
int minDepth(TreeNode* root) { if (root == NULL) { return 0; } if (isLeafNode(root)) { return 1; } // 处理左子树 int leftMinDepth = NOT_LEAF_NODE; // 防止把只有左子节点的二叉树的 minDepth 判断为 1(因为右子树 minDepth 为 0) if (root->left != NULL) { leftMinDepth = minDepth(root->left); } // 处理右子树 int rightMinDepth = NOT_LEAF_NODE; // 防止把只有右子节点的二叉树的 minDepth 判断为 1(因为左子树 minDepth 为 0) if (root->right != NULL) { rightMinDepth = minDepth(root->right); } // 返回:root 只有左子树 if (leftMinDepth != NOT_LEAF_NODE && rightMinDepth == NOT_LEAF_NODE) { return leftMinDepth + 1; } // 返回:root 只有右子树 if (leftMinDepth == NOT_LEAF_NODE && rightMinDepth != NOT_LEAF_NODE) { return rightMinDepth + 1; } // 返回:root 有左右子树 else { // 即 leftMinDepth != NOT_LEAF_NODE && rightMinDepth != NOT_LEAF_NODE return MIN_TWO(leftMinDepth, rightMinDepth) + 1; } }
void insert( const dataPoint &p ){ if( isLeafNode() ){ // We are a leaf node, and there is still room left if( data.size() < maxData ){ data.push_back( p ); } else { // No room left, create some children // TODO: Implement a max depth? for(int i=0;i<8;i++){ glm::vec3 nOrigin = origin; nOrigin.x += halfDim.x * (i&4 ? 0.5f : -0.5f ); nOrigin.y += halfDim.y * (i&2 ? 0.5f : -0.5f ); nOrigin.z += halfDim.z * (i&1 ? 0.5f : -0.5f ); children[i] = new Octree( nOrigin, halfDim * 0.5f, maxData ); } // Reorganize our data into child nodes typename std::vector< dataPoint >::iterator it; for( it = data.begin(); it != data.end(); it++){ children[ getOctantFromPoint( (*it).first ) ]->insert( (*it) ); } data.clear(); children[ getOctantFromPoint( p.first ) ]->insert( p ); } } else { // We are not a leaf node // Find best child to insert into findBestChild( p.first )->insert( p ); // We could just call children[ getOctantFromPoint(p.first) ]->insert(p) // But, this way we can (possibly) try to avoid too much recursion, // and it should be faster, as well. } }
// This is a really simple routine for querying the tree for points // within a bounding box defined by min/max points (bmin, bmax) // All results are pushed into 'results' void Container::getPointsInsideBox(Vector3 bmin, Vector3 bmax, std::vector<Body*>& results) { // If we're at a leaf node, just see if the current data point is inside // the query bounding box if(isLeafNode()) { if(bodies.size() > 0) { const Vector3& p = bodies[0]->pos; if(p.x>bmax.x || p.y>bmax.y || p.z>bmax.z) return; if(p.x<bmin.x || p.y<bmin.y || p.z<bmin.z) return; results.push_back(bodies[0]); } } else { // We're at an interior node of the tree. We will check to see if // the query bounding box lies outside the octants of this node. for(int i=0; i<8; ++i) { // Compute the min/max corners of this child octant Vector3 cmax = children[i]->pos + children[i]->halfSize; Vector3 cmin = children[i]->pos - children[i]->halfSize; // If the query rectangle is outside the child's bounding box, // then continue if(cmax.x<bmin.x || cmax.y<bmin.y || cmax.z<bmin.z) continue; if(cmin.x>bmax.x || cmin.y>bmax.y || cmin.z>bmax.z) continue; // At this point, we've determined that this child is intersecting // the query bounding box children[i]->getPointsInsideBox(bmin,bmax,results); } } }
virtual ~Octree(){ // Delete children if( !isLeafNode() ){ for(int i=0;i<8;i++){ delete children[i]; children[i] = NULL; } } }
//determine dimensions of small and large intervals and calculate F+(MAX), F-(SMALL) intervals. void calcNotTightUpperBound() { if(isLeafNode()) return calcTightUpperBound(); int score_plus = intervalSum(pos, intervalStart[Left], intervalEnd[Right]); upperbound = score_plus; }
void Crag::recLeafNodes(CragNode n, std::set<CragNode>& leafNodes) const { if (isLeafNode(n)) leafNodes.insert(n); else for (auto a : inArcs(n)) recLeafNodes(a.source(), leafNodes); }
/** Connect the start vertex to each of the vertices in \p tops. This is useful * temporarily for when we need to run a graph algorithm that expects a single * source vertex. */ void wireStartToTops(NGHolder &g, const map<u32, NFAVertex> &tops, vector<NFAEdge> &topEdges) { for (const auto &top : tops) { NFAVertex v = top.second; assert(!isLeafNode(v, g)); const NFAEdge &e = add_edge(g.start, v, g).first; topEdges.push_back(e); } }
QString ActorTypeTreeWidget::getCategoryOrName() { if (isLeafNode()) { return QString(mActorType->GetName().c_str()); } else { return mCategorySegment; } }
int Crag::getLevel(Crag::CragNode n) const { if (isLeafNode(n)) return 0; int level = 0; for (SubsetInArcIt e(getSubsetGraph(), toSubset(n)); e != lemon::INVALID; ++e) level = std::max(getLevel(toRag(getSubsetGraph().source(e))), level); return level + 1; }
void getOctantsInFrustum( const Frustum &frustum, std::vector< Octree<T>*> &out ){ int inFrustum = frustum.isBoxInFrustum( origin, halfDim ); if( inFrustum & 1 ){ // We are inside frustum if( inFrustum & 2 && !isLeafNode() ){ // Partially: for(int i=0;i<8;i++){ // Find and add visible children children[i]->getOctantsInFrustum( frustum, out ); } } else { // Completely: out.push_back( this ); } } }
void cleanup (trieNode **root) { if (isLeafNode(*root)) { return; } for (int i = 0; i < ALPHABET_SIZE; i++) { if ((*root)->next[i]) { cleanup((*root)->next[i]); removeNode((*root)->next[i]); } } }
bool hasPathSum(struct TreeNode *root, int sum) { #define STACK_SIZE 64 struct TreeNode *stack[STACK_SIZE] = {NULL}; struct TreeNode *aux_stack[STACK_SIZE] = {NULL}; struct TreeNode *node = NULL; int top = 0; int aux_top = 0; int total = 0; while (root != NULL) { stack[top++] = root; total += root->val; root = root->left; } while (top > 0) { node = stack[--top]; /* pop a node */ if (isLeafNode(node)) { if (total == sum) return true; } if (node->right != NULL && aux_top > 0 && node == aux_stack[aux_top-1]) { /* node's right child has been pushed before, that is to say node's value is added into total, * so minus it */ total -= node->val; aux_top--; } else if (node->right != NULL) { stack[top++] = node; /* here we let node which has right child re-push into stack again */ aux_stack[aux_top++] = node; /* we push node into auxiliary stack as records, so next time the node pops out, we would not push all its right childs into stack again (as these nodes have done before) */ node = node->right; while (node != NULL) { stack[top++] = node; total += node->val; node = node->left; } } else { total -= node->val; } } return false; }
static depth findMinWidth(const NGHolder &h, const SpecialEdgeFilter &filter, NFAVertex src) { if (isLeafNode(src, h)) { return depth::unreachable(); } boost::filtered_graph<NFAGraph, SpecialEdgeFilter> g(h.g, filter); assert(hasCorrectlyNumberedVertices(h)); const size_t num = num_vertices(h); vector<depth> distance(num, depth::unreachable()); distance.at(g[src].index) = depth(0); auto index_map = get(&NFAGraphVertexProps::index, g); // Since we are interested in the single-source shortest paths on a graph // with the same weight on every edge, using BFS will be faster than // Dijkstra here. breadth_first_search( g, src, visitor(make_bfs_visitor(record_distances( make_iterator_property_map(distance.begin(), index_map), boost::on_tree_edge()))).vertex_index_map(index_map)); DEBUG_PRINTF("d[accept]=%s, d[acceptEod]=%s\n", distance.at(NODE_ACCEPT).str().c_str(), distance.at(NODE_ACCEPT_EOD).str().c_str()); depth d = min(distance.at(NODE_ACCEPT), distance.at(NODE_ACCEPT_EOD)); if (d.is_unreachable()) { return d; } assert(d.is_finite()); assert(d > depth(0)); return d - depth(1); }
void Octree::checkCollisions(Entity *entityArray, Entity* entity, uint32 *collisionIndices, uint32 numChecks, uint32 *collisionsSoFar) { if(isLeafNode()) { for(uint32 i = 0; i < ArrayCount(entityReferenceBlock->entityReferences); ++i) { entity_reference *toCheck = entityReferenceBlock->entityReferences + i; do { if(toCheck->index) { if(doBoundsCollide(entity->model->aabb, entityArray[toCheck->index].model->aabb) && *collisionsSoFar < numChecks && !alreadyCollided(collisionIndices, numChecks, toCheck->index)) //don't want to collide with same entity stretching across multiple children { *(collisionIndices + *collisionsSoFar) = toCheck->index; (*collisionsSoFar)++; } } toCheck = toCheck->next; } while(toCheck); } } else { uint8 collidedChildren = whichChildren(entity->model->aabb); for(int32 i = 0; i < 8; ++i) { if((collidedChildren >> i) & 1) { children[i]->checkCollisions(entityArray, entity, collisionIndices, numChecks, collisionsSoFar); } } } }
static depth findMaxWidth(const NGHolder &h, const SpecialEdgeFilter &filter, NFAVertex src) { if (isLeafNode(src, h.g)) { return depth::unreachable(); } if (hasReachableCycle(h, src)) { // There's a cycle reachable from this src, so we have inf width. return depth::infinity(); } boost::filtered_graph<NFAGraph, SpecialEdgeFilter> g(h.g, filter); assert(hasCorrectlyNumberedVertices(h)); const size_t num = num_vertices(h); vector<int> distance(num); vector<boost::default_color_type> colors(num); auto index_map = get(&NFAGraphVertexProps::index, g); // DAG shortest paths with negative edge weights. dag_shortest_paths( g, src, distance_map(make_iterator_property_map(distance.begin(), index_map)) .weight_map(boost::make_constant_property<NFAEdge>(-1)) .vertex_index_map(index_map) .color_map(make_iterator_property_map(colors.begin(), index_map))); depth acceptDepth, acceptEodDepth; if (colors.at(NODE_ACCEPT) == boost::white_color) { acceptDepth = depth::unreachable(); } else { acceptDepth = -1 * distance.at(NODE_ACCEPT); } if (colors.at(NODE_ACCEPT_EOD) == boost::white_color) { acceptEodDepth = depth::unreachable(); } else { acceptEodDepth = -1 * distance.at(NODE_ACCEPT_EOD); } depth d; if (acceptDepth.is_unreachable()) { d = acceptEodDepth; } else if (acceptEodDepth.is_unreachable()) { d = acceptDepth; } else { d = max(acceptDepth, acceptEodDepth); } if (d.is_unreachable()) { // If we're actually reachable, we'll have a min width, so we can // return infinity in this case. if (findMinWidth(h, filter, src).is_reachable()) { return depth::infinity(); } return d; } // Invert sign and subtract one for start transition. assert(d.is_finite() && d > depth(0)); return d - depth(1); }
void Container::Insert(Body* point) { // If this node doesn't have a data point yet assigned // and it is a leaf, then we're done! if(isLeafNode() || myDepth == maxDepth) { if(bodies.size() < maxBodies) { bodies.push_back(point); return; } else { // We're at a leaf, but there's already max number of bodies here // We will split this node so that it has 8 child octants // and then insert the old data that was here, along with // this new data point // Save this data point that was here for a later re-insert std::vector<Body*> oldPoints = bodies; bodies.clear(); // Split the current node and create new empty trees for each // child octant. for(int i=0; i<8; ++i) { // Compute new bounding box for this child Vector3 newOrigin = pos; newOrigin.x += halfSize.x * (i&4 ? .5f : -.5f); newOrigin.y += halfSize.y * (i&2 ? .5f : -.5f); newOrigin.z += halfSize.z * (i&1 ? .5f : -.5f); children[i] = new Container(newOrigin, halfSize * 0.5f, maxBodies, myDepth + 1); } // Re-insert the old points, and insert this new point // (We wouldn't need to insert from the root, because we already // know it's guaranteed to be in this section of the tree) for(int i = 0; i < oldPoints.size(); i++) { // Check octant and sort into children or self int octant = getOctantContainingPoint(*oldPoints[0]); if(octant != 8) children[octant]->Insert(oldPoints[i]); else Place(point); } int octant = getOctantContainingPoint(*point); if(octant != 8) children[octant]->Insert(point); else Place(point); } } else { // We are at an interior node. Insert recursively into the // appropriate child octant int octant = getOctantContainingPoint(*point); if(octant != 8) children[octant]->Insert(point); else Place(point); } }
void GLWidget::debugDraw(unsigned rootInd, unsigned numInternal) { #ifdef BVHSOLVER_DBG_DRAW if(!m_solver->isValid()) return; GeoDrawer * dr = getDrawer(); // qDebug()<<" root at "<< (*m_rootNodeInd & (~0x80000000)); Aabb ab; BoundingBox bb; #ifdef BVHSOLVER_DBG_DRAW_BOX Aabb * internalBoxes = (Aabb *)m_displayInternalAabbs->data(); Aabb * leafBoxes = (Aabb *)m_displayLeafAabbs->data(); int * levels = (int *)m_displayInternalDistance->data(); KeyValuePair * leafHash = (KeyValuePair *)m_displayLeafHash->data(); int2 * internalNodeChildIndices = (int2 *)m_internalChildIndices->data(); // std::cout<<" "<<numInternal/2<<" "<<byte_to_binary(leafHash[numInternal/2].key)<<" "<<leafHash[numInternal/2].value<<"\n"; int stack[128]; stack[0] = rootInd; int stackSize = 1; int maxStack = 1; int touchedLeaf = 0; int touchedInternal = 0; while(stackSize > 0) { int internalOrLeafNodeIndex = stack[ stackSize - 1 ]; stackSize--; int isLeaf = isLeafNode(internalOrLeafNodeIndex); //Internal node if false uint bvhNodeIndex = getIndexWithInternalNodeMarkerRemoved(internalOrLeafNodeIndex); int bvhRigidIndex = (isLeaf) ? leafHash[bvhNodeIndex].value : -1; Aabb bvhNodeAabb = (isLeaf) ? leafBoxes[bvhRigidIndex] : internalBoxes[bvhNodeIndex]; { if(isLeaf) { #ifdef BVHSOLVER_DBG_DRAW_LEAFBOX glColor3f(.5, 0., 0.); ab = bvhNodeAabb; bb.setMin(ab.low.x, ab.low.y, ab.low.z); bb.setMax(ab.high.x, ab.high.y, ab.high.z); dr->boundingBox(bb); #endif touchedLeaf++; } else { #ifdef BVHSOLVER_DBG_DRAW_INTERNALBOX_TO_LEVEL glColor3f(.5, .65, 0.); if(levels[bvhNodeIndex] > m_displayLevel) continue; ab = bvhNodeAabb; bb.setMin(ab.low.x, ab.low.y, ab.low.z); bb.setMax(ab.high.x, ab.high.y, ab.high.z); dr->boundingBox(bb); #endif touchedInternal++; if(stackSize + 2 > 128) { //Error } else { stack[ stackSize ] = internalNodeChildIndices[bvhNodeIndex].x; stackSize++; stack[ stackSize ] = internalNodeChildIndices[bvhNodeIndex].y; stackSize++; if(stackSize > maxStack) maxStack = stackSize; } } } } //qDebug()<<"max stack "<<maxStack<<" touch leaf "<<touchedLeaf<<" touchedInternal "<<touchedInternal; #endif #ifdef BVHSOLVER_DBG_DRAW_LEAFHASH glBegin(GL_LINES); int nzero = 0; for(unsigned i=0; i < numInternal; i++) { float red = (float)i/(float)numInternal; if(leafHash[i].value > numInternal) { qDebug()<<"invalid hash value "<<leafHash[i].value; nzero++; continue; } glColor3f(red, 1.f - red, 0.f); Aabb a0 = leafBoxes[leafHash[i].value]; glVertex3f(a0.low.x * 0.5f + a0.high.x * 0.5f, a0.low.y * 0.5f + a0.high.y * 0.5f + 0.2f, a0.low.z * 0.5f + a0.high.z * 0.5f); Aabb a1 = leafBoxes[leafHash[i+1].value]; glVertex3f(a1.low.x * 0.5f + a1.high.x * 0.5f, a1.low.y * 0.5f + a1.high.y * 0.5f + 0.2f, a1.low.z * 0.5f + a1.high.z * 0.5f); } glEnd(); if(nzero > 0) qDebug()<<"n zero code "<<nzero; #endif #endif #ifdef BVHSOLVER_DBG_DRAW_RAY RayInfo * rays = m_ray->getRays(); const unsigned nr = m_ray->numRays(); glColor3f(0.f, 0.5f, 0.2f); glBegin(GL_LINES); for(unsigned i=0; i < nr; i++) { RayInfo & r = rays[i]; glVertex3f(r.origin.x, r.origin.y, r.origin.z); glVertex3f(r.destiny.x, r.destiny.y, r.destiny.z); Vector3F a(r.destiny.x - r.origin.x, r.destiny.y - r.origin.y, r.destiny.z - r.origin.z); // qDebug()<<" "<<a.length(); } glEnd(); #endif }
AVLTree AVLDeleteElement(int element, AVLTree tree){ AVLTree node = tree; bool found = false; while (node) { long diff = node->element - element; if(diff == 0){ found = true; break; } if(diff>0){ node = node->left; }else{ node = node->right; } } if(found){ AVLTree labelNode = NULL; if(isLeafNode(node)){ //if leaf node, delete directly; //not root node; if(node->parent){ deConnect(node); }else{ tree = NULL; } labelNode = node->parent; free(node); }else if(node->right){ AVLTree minNode = findMinNode(node->right); node->element = minNode->element; deConnect(minNode); free(minNode); labelNode = minNode->parent; }else{ labelNode = node->parent; if(labelNode){ connectParentAndSon(labelNode, node->left, 0); } if(!labelNode){ tree = node->left; } free(node); } //find the node, heigh maybe changed. -- labelNode; if(labelNode){ //start from label, find which node need roate; AVLTree adjustNode = getRotateNode(labelNode); if(adjustNode){ AVLTree parentNode = NULL; parentNode = adjustNode->parent; long leftOrRight = leftOrRight = findWhichSon(parentNode, adjustNode); AVLTree newNode = rotate(adjustNode); if(leftOrRight != -1){ connectParentAndSon(parentNode, newNode, leftOrRight); }else{ //after rotate, root changed; tree = newNode; } } } } return tree; }