tree *delete_tree(tree *t, int k) { tree * x = Descend(t, k); if (x == NULL) printf("lol1\n"); if (x->left == NULL && x->right == NULL) t = ReplaceNode(t, x, NULL); else if (x->left == NULL) t = ReplaceNode(t, x, x->right); else if (x->right == NULL) t = ReplaceNode(t, x, x->left); else { tree * y = succ(x); t = ReplaceNode(t, y, y->right); x->left->parent = y; y->left = x->left; if (x->right != NULL) x->right->parent = y; y->right = x->right; t = ReplaceNode(t, x, y); //y->count = x->count; } free(x->word); free(x); return t; }
/* * Elimina un nodo del árbol. */ void DeleteString(int p) { int replacement; /* Si el nodo a borrar no está en el árbol, no hacemos nada. */ if ( tree[ p ].parent == UNUSED ) return; /* Si el nodo a borrar sólo tiene un hijo, hacemos una contracción del árbol. */ if ( tree[ p ].larger_child == UNUSED ) ContractNode( p, tree[ p ].smaller_child ); else if ( tree[ p ].smaller_child == UNUSED ) ContractNode( p, tree[ p ].larger_child ); /* Si el nodo a borrar tiene ambos descendientes. */ else { /* Localizamos el siguiente nodo más pequeño que el nodo que intentamos borrar. */ replacement = FindNextNode( p ); /* Eliminaos el siguiente nodo más pequeño del árbol. Nótese que el nodo "replacemente" nunca va a tener los dos descendientes, lo que evita entrar en más de un nivel de recursión. */ DeleteString( replacement ); /* Sustituimos el nodo que estamos intentanbo borrar por el que acabamos de localizar y eliminar el árbol. */ ReplaceNode( p, replacement ); } }
/* * Play the "animal" game, in which the program attempts to guess an animal * that the user is thinking of by asking yes or no questions. Eventually, * the program either will guess the user's animal or run out of questions * to ask. In the latter case, the program will ask the user to provide a * yes-or-no question that would distinguish between the user's animal and * the program's best guess. * The data structure of questions and guesses is essentially a binary tree, * with each internal node having a "yes" branch and a "no" branch. Leaves * of the tree represent animals to be guessed by the program. If the program * fails to guess the user's animal, it replaces one of the leaves of the tree * by a node containing the new question, whose children are the program's * best guess and the animal provided by the user. * The structure of the program is simple. It initializes the question/guess * data structure, then plays games as long as the user is interested. In each * game, the program starts at the top of the tree (the root) and progresses * toward the bottom (the leaves) depending on the user's responses. Once it * reaches a leaf, it either has won or lost, and handles the situation as * described above. */ int main () { TreeType tree; PositionType pos; char *newQuestion, *newAnswer; tree = InitTree (); // unitTest(); printf("%s", "Think of an animal. I will try to guess what it is.\n" "Please answer my questions with yes or no.\n"); while (TRUE) { pos = Top (tree); while (!IsLeaf (tree, pos)) { pos = Answer (Question (tree, pos))? YesNode (tree, pos): NoNode (tree, pos); } if (Answer (Guess (tree, pos))) { printf ("I got it right!\n"); } else { GetNewInfo (tree, pos, &newAnswer, &newQuestion); ReplaceNode (tree, pos, newAnswer, newQuestion); } if (!Answer ("Want to play again? ")) { exit (0); } } return 0; }
/* * Play the "animal" game, in which the program attempts to guess an animal * that the user is thinking of by asking yes or no questions. Eventually, * the program either will guess the user's animal or run out of questions * to ask. In the latter case, the program will ask the user to provide a * yes-or-no question that would distinguish between the user's animal and * the program's best guess. * The data structure of questions and guesses is essentially a binary tree, * with each internal node having a "yes" branch and a "no" branch. Leaves * of the tree represent animals to be guessed by the program. If the program * fails to guess the user's animal, it replaces one of the leaves of the tree * by a node containing the new question, whose children are the program's * best guess and the animal provided by the user. * The structure of the program is simple. It initializes the question/guess * data structure, then plays games as long as the user is interested. In each * game, the program starts at the top of the tree (the root) and progresses * toward the bottom (the leaves) depending on the user's responses. Once it * reaches a leaf, it either has won or lost, and handles the situation as * described above. */ int main (int argc, char *argv[]) { char *treefile = NULL; TreeType tree; PositionType pos; char *newQuestion, *newAnswer; if (argc > 1) { treefile = argv[1]; } tree = InitTree (treefile); printf("%s", "Think of an animal. I will try to guess what it is.\n" "Please answer my questions with yes or no.\n"); while (TRUE) { pos = Top (tree); while (!IsLeaf (tree, pos)) { pos = Answer(Question(tree,pos))? YesNode(tree,pos): NoNode(tree,pos); } if (Answer (Guess (tree, pos))) { printf ("I got it right!\n"); } else { GetNewInfo (tree, pos, &newAnswer, &newQuestion); ReplaceNode (tree, pos, newAnswer, newQuestion); } if (!Answer ("Want to play again? ")) { WriteTree(tree, treefile); exit (0); } } }
void APICALL DOMParserImpl::ParseWithSpecificAction( const char * buffer, sizet bufferLength, eActionType actionType, spINode & node ) { auto parsedNode = ParseAsNode( buffer, bufferLength ); if ( parsedNode ) { switch ( actionType ) { case kATAppendAsChildren: AppendAsChildren( node, parsedNode ); break; case kATReplaceChildren: ReplaceChildren( node, parsedNode ); break; case kATAppendOrReplaceChildren: AppendOrReplaceChildren( node, parsedNode ); break; case kATInsertBefore: InsertBefore( node, parsedNode ); break; case kATInsertAfter: InsertAfter( node, parsedNode ); break; case kATReplace: ReplaceNode( node, parsedNode ); break; default: NOTIFY_ERROR( IError::kEDGeneral, kGECNotImplemented, "Not yet implemented", IError::kESOperationFatal, true, static_cast< sizet >( actionType ) ); } } }
void RedBlackTree::RotateRight(RBNode* node) { RBNode* l = node->left; ReplaceNode(node, l); node->parent = l; node->left = l->right; l->right = node; }
void RedBlackTree::RotateLeft(RBNode* node) { RBNode* r = node->right; ReplaceNode(node, r); node->parent = r; node->right = r->right; r->left = node; }
/* * Esta rutina inserta un nuevo nodo al árbol binario y encuentra * (retornando) la mejor ocurrencia de la cadena buscada. */ int AddString(int new_node, int *match_position) { int i; int test_node; int delta; int match_length; int *child; /* Estamos insertando el símbolo END_OF_STREAM? */ if ( new_node == END_OF_STREAM ) return 0; /* Accedemos a la raíz del árbol y de ahí al primer nodo con datos almacenado. */ test_node = tree[ TREE_ROOT ].larger_child; /* La longitud de la cadena encontrada es todavía, 0. */ match_length = 0; for ( ; ; ) { /* "i" contiene el "match_length" actual. */ for ( i = 0 ; i < LOOK_AHEAD_SIZE ; i++ ) { /* "delta" < 1 si la cadena almacenada en "new_node" es menor que la de "test_node", "delta" = 0 si son iguales y "delta" > 1 si la cadena en "nee_node" es mayor que la de "test_node". */ delta = window[ MOD_WINDOW( new_node + i ) ] - window[ MOD_WINDOW( test_node + i ) ]; if ( delta != 0 ) break; } /* Si hemos encontrado una cadena más larga. */ if ( i >= match_length ) { match_length = i; *match_position = test_node; /* Si hemos encontrado todo el buffer de anticipación en el diccionario (ya no es posible buscar una cadena más larga). */ if ( match_length >= LOOK_AHEAD_SIZE ) { /* "new_node" reemplaza a "test_node" para manterner el árbol lo más pequeño posible, sin afectar a la tasa de compresión. */ ReplaceNode( test_node, new_node ); return match_length; } } /* Navegación binaria sobre el árbol. */ if ( delta >= 0 ) child = &tree[ test_node ].larger_child; else child = &tree[ test_node ].smaller_child; if ( *child == UNUSED ) { *child = new_node; tree[ new_node ].parent = test_node; tree[ new_node ].larger_child = UNUSED; tree[ new_node ].smaller_child = UNUSED; return match_length; } test_node = *child; } }
static void SwapNodes( ubi_btRootPtr RootPtr, ubi_btNodePtr Node1, ubi_btNodePtr Node2 ) /* ------------------------------------------------------------------------ ** * This function swaps two nodes in the tree. Node1 will take the place of * Node2, and Node2 will fill in the space left vacant by Node 1. * * Input: * RootPtr - pointer to the tree header structure for this tree. * Node1 - \ * > These are the two nodes which are to be swapped. * Node2 - / * * Notes: * This function does a three step swap, using a dummy node as a place * holder. This function is used by ubi_btRemove(). * ------------------------------------------------------------------------ ** */ { ubi_btNodePtr *Parent; ubi_btNode dummy; ubi_btNodePtr dummy_p = &dummy; /* Replace Node 1 with the dummy, thus removing Node1 from the tree. */ if( NULL != Node1->Link[ubi_trPARENT] ) Parent = &((Node1->Link[ubi_trPARENT])->Link[(int)(Node1->gender)]); else Parent = &(RootPtr->root); ReplaceNode( Parent, Node1, dummy_p ); /* Swap Node 1 with Node 2, placing Node 1 back into the tree. */ if( NULL != Node2->Link[ubi_trPARENT] ) Parent = &((Node2->Link[ubi_trPARENT])->Link[(int)(Node2->gender)]); else Parent = &(RootPtr->root); ReplaceNode( Parent, Node2, Node1 ); /* Swap Node 2 and the dummy, thus placing Node 2 back into the tree. */ if( NULL != dummy_p->Link[ubi_trPARENT] ) Parent = &((dummy_p->Link[ubi_trPARENT])->Link[(int)(dummy_p->gender)]); else Parent = &(RootPtr->root); ReplaceNode( Parent, dummy_p, Node2 ); } /* SwapNodes */
void Interpose(OBJECT z, int typ, OBJECT x, OBJECT y) { OBJECT encl; New(encl, typ); FposCopy(fpos(encl), fpos(y)); ReplaceNode(encl, z); Link(encl, z); back(encl, COLM) = back(x, COLM); fwd(encl, COLM) = fwd(x, COLM); back(encl, ROWM) = back(y, ROWM); fwd(encl, ROWM) = fwd(y, ROWM); underline(encl) = underline(z); } /* end Interpose */
static OBJECT InterposeWideOrHigh(OBJECT y, int dim) { OBJECT res; New(res, dim == COLM ? WIDE : HIGH); FposCopy(fpos(res), fpos(y)); back(res, dim) = back(y, dim); fwd(res, dim) = fwd(y, dim); back(res, 1-dim) = back(y, 1-dim); fwd(res, 1-dim) = fwd(y, 1-dim); SetConstraint(constraint(res), MAX_FULL_LENGTH, size(res, dim), MAX_FULL_LENGTH); ReplaceNode(res, y); Link(res, y); return res; } /* end InterposeWideOrHigh */
int AddString ( int new_node, int *match_pos) { int i; int test_node; int delta; int match_len; int *child; if (new_node == END_OF_STREAM) return (0); test_node = tree [TREE_ROOT].larger_child; match_len = 0; for (;;) { for ( i = 0; i < LOOK_AHEAD_SIZE; i++) { delta = window [MODULO (new_node + i)] - window [MODULO (test_node + i)]; if (delta != 0) break; } if (i >= match_len) { match_len = i; *match_pos = test_node; if (match_len >= LOOK_AHEAD_SIZE) { ReplaceNode ( test_node, new_node); return match_len; } } if (delta >= 0) child = &tree [test_node].larger_child; else child = &tree [test_node].smaller_child; if (*child == UNUSED) { *child = new_node; tree [new_node].parent = test_node; tree [new_node].larger_child = UNUSED; tree [new_node].smaller_child = UNUSED; return match_len; } test_node = *child; } }
void unitTest() { TreeType tree = InitTree(); printf("After initlizing tree:\n"); PrintTree(tree); PositionType question = 0; PositionType answer = 5; printf("IsLeaf test 1: %s\n", IsLeaf(tree, question) ? "error" : "pass"); printf("IsLeaf test 2: %s\n", IsLeaf(tree, answer) ? "pass" : "error"); printf("Top test: %s\n", Top(tree) == 0 ? "pass" : "error"); printf("Question test 1: %s\n", strcmp(Question(tree, question), "Is it furry?") == 0 ? "pass" : "error"); printf("Question test 2: %s\n", strcmp(Question(tree, answer), "Is it a lizard?") == 0 ? "pass" : "error"); printf("%s\n", Question(tree, answer)); ReplaceNode(tree, 7, "a kitten", "Is it an adult?"); PrintTree(tree); }
//---------------------------------------------------------------------------- // Удаление строки из двоичного дерева поиска void DeleteString ( int p) { int replacement; if (tree [p].parent == UNUSED) return; if (tree [p].larger_child == UNUSED) ContractNode ( p, tree [p].smaller_child); else if (tree [p].smaller_child == UNUSED) ContractNode ( p, tree [p].larger_child); else { replacement = FindNextNode (p); DeleteString (replacement); ReplaceNode ( p, replacement); } }
static OBJECT InterposeScale(OBJECT y, int scale_factor, int dim) { OBJECT res; New(res, SCALE); FposCopy(fpos(res), fpos(y)); if( dim == COLM ) { bc(constraint(res)) = scale_factor; fc(constraint(res)) = 1 * SF; } else { bc(constraint(res)) = 1 * SF; fc(constraint(res)) = scale_factor; } back(res, dim) = (back(y, dim) * scale_factor) / SF; fwd(res, dim) = (fwd(y, dim) * scale_factor) / SF; back(res, 1-dim) = back(y, 1-dim); fwd(res, 1-dim) = fwd(y, 1-dim); ReplaceNode(res, y); Link(res, y); return res; } /* end InterposeScale */
ubi_trBool ubi_btInsert( ubi_btRootPtr RootPtr, ubi_btNodePtr NewNode, ubi_btItemPtr ItemPtr, ubi_btNodePtr *OldNode ) /* ------------------------------------------------------------------------ ** * This function uses a non-recursive algorithm to add a new element to the * tree. * * Input: RootPtr - a pointer to the ubi_btRoot structure that indicates * the root of the tree to which NewNode is to be added. * NewNode - a pointer to an ubi_btNode structure that is NOT * part of any tree. * ItemPtr - A pointer to the sort key that is stored within * *NewNode. ItemPtr MUST point to information stored * in *NewNode or an EXACT DUPLICATE. The key data * indicated by ItemPtr is used to place the new node * into the tree. * OldNode - a pointer to an ubi_btNodePtr. When searching * the tree, a duplicate node may be found. If * duplicates are allowed, then the new node will * be simply placed into the tree. If duplicates * are not allowed, however, then one of two things * may happen. * 1) if overwritting *is not* allowed, this * function will return FALSE (indicating that * the new node could not be inserted), and * *OldNode will point to the duplicate that is * still in the tree. * 2) if overwritting *is* allowed, then this * function will swap **OldNode for *NewNode. * In this case, *OldNode will point to the node * that was removed (thus allowing you to free * the node). * ** If you are using overwrite mode, ALWAYS ** * ** check the return value of this parameter! ** * Note: You may pass NULL in this parameter, the * function knows how to cope. If you do this, * however, there will be no way to return a * pointer to an old (ie. replaced) node (which is * a problem if you are using overwrite mode). * * Output: a boolean value indicating success or failure. The function * will return FALSE if the node could not be added to the tree. * Such failure will only occur if duplicates are not allowed, * nodes cannot be overwritten, AND a duplicate key was found * within the tree. * ------------------------------------------------------------------------ ** */ { ubi_btNodePtr OtherP, parent = NULL; char tmp; if( NULL == OldNode ) /* If they didn't give us a pointer, supply our own. */ OldNode = &OtherP; (void)ubi_btInitNode( NewNode ); /* Init the new node's BinTree fields. */ /* Find a place for the new node. */ *OldNode = TreeFind(ItemPtr, (RootPtr->root), &parent, &tmp, (RootPtr->cmp)); /* Now add the node to the tree... */ if( NULL == (*OldNode) ) /* The easy one: we have a space for a new node! */ { if( NULL == parent ) RootPtr->root = NewNode; else { parent->Link[(int)tmp] = NewNode; NewNode->Link[ubi_trPARENT] = parent; NewNode->gender = tmp; } (RootPtr->count)++; return( ubi_trTRUE ); } /* If we reach this point, we know that a duplicate node exists. This * section adds the node to the tree if duplicate keys are allowed. */ if( ubi_trDups_OK(RootPtr) ) /* Key exists, add duplicate */ { ubi_btNodePtr q; tmp = ubi_trRIGHT; q = (*OldNode); *OldNode = NULL; while( NULL != q ) { parent = q; if( tmp == ubi_trEQUAL ) tmp = ubi_trRIGHT; q = q->Link[(int)tmp]; if ( q ) tmp = ubi_trAbNormal( (*(RootPtr->cmp))(ItemPtr, q) ); } parent->Link[(int)tmp] = NewNode; NewNode->Link[ubi_trPARENT] = parent; NewNode->gender = tmp; (RootPtr->count)++; return( ubi_trTRUE ); } /* If we get to *this* point, we know that we are not allowed to have * duplicate nodes, but our node keys match, so... may we replace the * old one? */ if( ubi_trOvwt_OK(RootPtr) ) /* Key exists, we replace */ { if( NULL == parent ) ReplaceNode( &(RootPtr->root), *OldNode, NewNode ); else ReplaceNode( &(parent->Link[(int)((*OldNode)->gender)]), *OldNode, NewNode ); return( ubi_trTRUE ); } return( ubi_trFALSE ); /* Failure: could not replace an existing node. */ } /* ubi_btInsert */
void CChildView::ReplaceSelectedWithType(NodeType Type) { std::vector<CNodeBase*> newSelected; PrintOut(_T("Replace Node Type %Ts"), NodeTypeToString(Type)); for (UINT i = 0; i < Selected.size(); i++) { if (!theApp.IsNodeValid(Selected[i].object)) continue; if (Selected[i].object->pParent->GetType() == nt_vtable) Type = nt_function; CNodeBase* pNewNode = theApp.CreateNewNode(Type); if (Type == nt_class) MakeBasicClass((CNodeClass*)pNewNode); if (Type == nt_custom) ((CNodeCustom*)pNewNode)->memsize = Selected[i].object->GetMemorySize(); if (Type == nt_text) ((CNodeText*)pNewNode)->memsize = Selected[i].object->GetMemorySize(); if (Type == nt_unicode) ((CNodeUnicode*)pNewNode)->memsize = Selected[i].object->GetMemorySize(); if (Type == nt_vtable) { for (int i = 0; i < 10; i++) { CNodeVTable* pVTable = (CNodeVTable*)pNewNode; CNodeFunctionPtr* pFun = new CNodeFunctionPtr; pFun->offset = i * 8; pFun->pParent = pVTable; pVTable->Nodes.push_back(pFun); } } if (Type == nt_pointer) { CNodePtr* pPtr = (CNodePtr*)pNewNode; CNodeClass* pClass = (CNodeClass*)theApp.CreateNewNode(nt_class); MakeBasicClass(pClass); pPtr->pNode = pClass; } if (Type == nt_array) { CNodeArray* pArray = (CNodeArray*)pNewNode; CNodeClass* pClass = (CNodeClass*)theApp.CreateNewNode(nt_class); MakeBasicClass(pClass); pArray->pNode = pClass; } if (Type == nt_instance) { CNodeClassInstance* pInstance = (CNodeClassInstance*)pNewNode; CNodeClass* pClass = (CNodeClass*)theApp.CreateNewNode(nt_class); MakeBasicClass(pClass); pInstance->pNode = pClass; } ReplaceNode((CNodeClass*)Selected[i].object->pParent, FindNodeIndex(Selected[i].object), pNewNode); newSelected.push_back(pNewNode); } Selected.clear(); for (UINT i = 0; i < newSelected.size(); i++) { newSelected[i]->bSelected = true; CNodeClass* pClass = (CNodeClass*)newSelected[i]->pParent; HotSpot spot; spot.Address = pClass->offset + newSelected[i]->offset; spot.object = newSelected[i]; Selected.push_back(spot); } Invalidate(FALSE); }
OBJECT ClosureExpand(OBJECT x, OBJECT env, BOOLEAN crs_wanted, OBJECT *crs, OBJECT *res_env) { OBJECT link, y, res, prnt_env, par, prnt; debug3(DCE, D, "[ ClosureExpand( %s, %s, %s, crs, res_env )", EchoObject(x), EchoObject(env), bool(crs_wanted)); assert( type(x) == CLOSURE, "ClosureExpand given non-CLOSURE!"); assert( predefined(actual(x)) == FALSE, "ClosureExpand given predefined!" ); /* add tag to x if needed but not provided; add cross-reference to crs */ if( has_tag(actual(x)) ) CrossAddTag(x); if( crs_wanted && has_tag(actual(x)) ) { OBJECT tmp = CopyObject(x, no_fpos); AttachEnv(env, tmp); y = CrossMake(actual(x), tmp, CROSS_TARG); New(tmp, CROSS_TARG); actual(tmp) = y; Link(tmp, y); if( *crs == nilobj ) New(*crs, CR_LIST); Link(*crs, tmp); } /* case x is a parameter */ res = *res_env = nilobj; if( is_par(type(actual(x))) ) { prnt = SearchEnv(env, enclosing(actual(x))); if( prnt != nilobj ) { prnt_env = GetEnv(prnt); for( link = Down(prnt); link != prnt; link = NextDown(link) ) { Child(par, link); if( type(par) == PAR && actual(par) == actual(x) ) { assert( Down(par) != par, "ExpandCLosure: Down(par)!"); Child(res, Down(par)); if( dirty(enclosing(actual(par))) || is_enclose(actual(par)) ) { debug2(DCE, DD, "copy %s %s", SymName(actual(par)), EchoObject(res)); res = CopyObject(res, no_fpos); } else { debug2(DCE, DD, "link %s %s", FullSymName(actual(par), AsciiToFull(".")), EchoObject(res)); DeleteLink(Down(par)); y = MakeWord(WORD, STR_NOCROSS, &fpos(res)); Link(par, y); } ReplaceNode(res, x); if( type(actual(x)) == RPAR && has_body(enclosing(actual(x))) ) { debug0(DCR, DDD, " calling SetEnv from ClosureExpand (a)"); *res_env = SetEnv(prnt, nilobj); DisposeObject(x); } else if( type(actual(x)) == NPAR && imports_encl(actual(x)) ) { debug0(DCR, DDD, " calling SetEnv from ClosureExpand (x)"); AttachEnv(env, x); *res_env = SetEnv(x, nilobj); } else { AttachEnv(env, x); debug0(DCR, DDD, " calling SetEnv from ClosureExpand (b)"); *res_env = SetEnv(x, prnt_env); } break; } } } else { /* fail only if there is no default value available */ if( sym_body(actual(x)) == nilobj ) { debug3(DCE, D, "failing ClosureExpand( %s, crs, %s, %s, res_env )", EchoObject(x), bool(crs_wanted), EchoObject(env)); Error(9, 2, "no value for parameter %s of symbol %s:", WARN, &fpos(x), SymName(actual(x)), SymName(enclosing(actual(x)))); Error(9, 1, "symbol with import list misused", FATAL, &fpos(x)); } } } /* case x is a user-defined symbol or default parameter */ if( res == nilobj ) { if( sym_body(actual(x)) == nilobj ) res = MakeWord(WORD, STR_NOCROSS, &fpos(x)); else res = CopyObject(sym_body(actual(x)), &fpos(x)); ReplaceNode(res, x); AttachEnv(env, x); debug0(DCR, DDD, " calling SetEnv from ClosureExpand (c)"); *res_env = SetEnv(x, nilobj); } assert( *res_env!=nilobj && type(*res_env)==ENV, "ClosureExpand: *res_env!"); debug0(DCE, D, "] ClosureExpand returning, res ="); ifdebug(DCE, D, DebugObject(res)); debug1(DCE, D, " environment = %s", EchoObject(*res_env)); return res; } /* end ClosureExpand */