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;

}
示例#3
0
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;
}
示例#4
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++;
}
示例#5
0
    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;
        }
    }
示例#6
0
    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.
        }
    }
示例#7
0
// 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);
		} 
	}
}
示例#8
0
 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;
	}
示例#10
0
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);
}
示例#11
0
/** 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);
    }
}
示例#12
0
 QString ActorTypeTreeWidget::getCategoryOrName()
 {
    if (isLeafNode())
    {
       return QString(mActorType->GetName().c_str());
    }
    else
    {
       return mCategorySegment;
    }
 }
示例#13
0
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;
}
示例#14
0
 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 );
         }
     }
 }
示例#15
0
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]);
		}
	}
}
示例#16
0
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;
}
示例#17
0
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);
}
示例#18
0
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);
            }
        }
    }
}
示例#19
0
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);
}
示例#20
0
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);
	}
}
示例#21
0
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
}
示例#22
0
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;
}