Beispiel #1
0
void BSTDelete (tBSTNodePtr *RootPtr, char K) 		{
/*   ---------
** Zru¹í uzel stromu, který obsahuje klíè K.
**
** Pokud uzel se zadaným klíèem neexistuje, nedìlá funkce nic. 
** Pokud má ru¹ený uzel jen jeden podstrom, pak jej zdìdí otec ru¹eného uzlu.
** Pokud má ru¹ený uzel oba podstromy, pak je ru¹ený uzel nahrazen nejpravìj¹ím
** uzlem levého podstromu. Pozor! Nejpravìj¹í uzel nemusí být listem.
**
** Tuto funkci implementujte rekurzivnì s vyu¾itím døíve deklarované
** pomocné funkce ReplaceByRightmost.
**/
	
	tBSTNodePtr help_ptr = NULL;	// pomocny ukazatel

	if ( (*RootPtr) != NULL ){
		if ( (*RootPtr)->Key > K )
			BSTDelete(&((*RootPtr)->LPtr), K); // hledej v levem podstromu
		else if ( (*RootPtr)->Key < K )
			BSTDelete(&((*RootPtr)->RPtr), K); // hledej v pravem podstromu
		else{	// budeme rusit uzel
			help_ptr = *RootPtr; // preulozeni ukazatele
			if ( help_ptr->LPtr == NULL ){	// obsahuje jen pravy podstrom?
				*RootPtr = help_ptr->RPtr;
				free(help_ptr);
			}
			else if ( help_ptr->RPtr == NULL ){	// obsahuje jen levy podstrom?
				*RootPtr = help_ptr->LPtr;
				free(help_ptr);
			}
			else // uzel obsahuje oba podstromy, budeme hledat nejpravejsi prvek
				ReplaceByRightmost(*RootPtr, (&((*RootPtr)->LPtr)));
		}
	}
} 
Beispiel #2
0
void BSTDelete (tBSTNodePtr *RootPtr, char K)     {
/*   ---------
** Zru¹í uzel stromu, který obsahuje klíè K.
**
** Pokud uzel se zadaným klíèem neexistuje, nedìlá funkce nic.
** Pokud má ru¹ený uzel jen jeden podstrom, pak jej zdìdí otec ru¹eného uzlu.
** Pokud má ru¹ený uzel oba podstromy, pak je ru¹ený uzel nahrazen nejpravìj¹ím
** uzlem levého podstromu. Pozor! Nejpravìj¹í uzel nemusí být listem.
**
** Tuto funkci implementujte rekurzivnì s vyu¾itím døíve deklarované
** pomocné funkce ReplaceByRightmost.
**/
  if(*RootPtr!=NULL){               //neprazdny strom
    if((*RootPtr)->Key==K){         //prvek nalezen
      tBSTNodePtr ptr=(*RootPtr);
      if((*RootPtr)->LPtr==NULL){      //prvek nema leveho syna
        *RootPtr=(*RootPtr)->RPtr;
        free(ptr);
      }else if((*RootPtr)->RPtr==NULL){//prvek nema praveho syna
        *RootPtr=(*RootPtr)->LPtr;
        free(ptr);
      }else                            //prvek ma oba syny
        ReplaceByRightmost(*RootPtr,&((*RootPtr)->LPtr));
    }else if((*RootPtr)->Key>K)     //prvek je u leveho syna
      BSTDelete(&((*RootPtr)->LPtr),K);
    else                            //prvek je u praveho syna
      BSTDelete(&((*RootPtr)->RPtr),K);
  }
}
Beispiel #3
0
void ReplaceByRightmost (tBSTNodePtr PtrReplaced, tBSTNodePtr *RootPtr) {
/*   ------------------
** Pomocná funkce pro vyhledání, pøesun a uvolnìní nejpravìj¹ího uzlu.
**
** Ukazatel PtrReplaced ukazuje na uzel, do kterého bude pøesunuta hodnota
** nejpravìj¹ího uzlu v podstromu, který je urèen ukazatelem RootPtr.
** Pøedpokládá se, ¾e hodnota ukazatele RootPtr nebude NULL (zajistìte to
** testováním pøed volání této funkce). Tuto funkci implementujte rekurzivnì. 
**
** Tato pomocná funkce bude pou¾ita dále. Ne¾ ji zaènete implementovat,
** pøeètìte si komentáø k funkci BSTDelete(). 
**/
	
	tBSTNodePtr help_ptr = NULL; //	pomocny ukazatel

	if ( *RootPtr != NULL ){
		if( (*RootPtr)->RPtr != NULL )	// overeni, jestli je opravdu nejpravejsi
			ReplaceByRightmost(PtrReplaced, (&((*RootPtr)->RPtr)));	// posun doprava
		else{
			PtrReplaced->Key = (*RootPtr)->Key;  //	prepis klic
			PtrReplaced->BSTNodeCont = (*RootPtr)->BSTNodeCont; // prepis obsah
			help_ptr = *RootPtr;	// preulozeni ukazatele
			*RootPtr = (*RootPtr)->LPtr; // uvolneni uzlu

			free(help_ptr);	// odstraneni pomocneho ukazatele
		}
	}
	
}
Beispiel #4
0
/* POZOR NASLEDUJÍCÍ PROCEDURA BUDE POU®ITA DÁLE, 
** PREÈTÌTE SI PROTO PODROBNÌ NEJPRVE KOMENTÁØ K PROCEDUØE BSTDELETE(),
** NE® ZAÈNETE VYTVÁØET REPLACEBYRIGHTMOST().
*/
void ReplaceByRightmost (tBSTNodePtr PtrReplaced,tBSTNodePtr *RootPtr) {
/* Pomocná procedura pro vyhledání, pøestìhování a uvolnìní nejpravìj¹ího
** uzlu v podstromu urèeném ukazatelem RootPtr. Na vstupu se pøedpokládá
** hodnota ukazatele RootPtr rùzná od NULL (zajistìte to testováním pøed
** volání procedury). Dále se pøedpokládá, ¾e pomocný ukazatel PtrReplaced
** ukazuje na uzel, který se má naplnit hodnotami vyhledaného uzlu.
*/
  tBSTNodePtr ptr; /* pou¾ívejte tento pomocný ukazatel */
  ptr = NULL;
  
  if(*RootPtr){
    if((*RootPtr)->RPtr != NULL) {
      ReplaceByRightmost(PtrReplaced, &((*RootPtr)->RPtr));
    }
    else if((*RootPtr)->RPtr == NULL && (*RootPtr)->LPtr != NULL) {
      PtrReplaced->Key = (*RootPtr)->Key;
      PtrReplaced->BSTNodeCont = (*RootPtr)->BSTNodeCont;
      ptr = PtrReplaced->LPtr;
      PtrReplaced->LPtr = (*RootPtr)->LPtr;
      free(ptr);
    }
    else {
      ptr = (*RootPtr);
      PtrReplaced->Key = (*RootPtr)->Key;
      PtrReplaced->BSTNodeCont = (*RootPtr)->BSTNodeCont;
      free(ptr);
      *RootPtr = NULL;
    }
  }  

}
Beispiel #5
0
void ReplaceByRightmost (tBSTNodePtr PtrReplaced, tBSTNodePtr *RootPtr)
{
	if ( *RootPtr != NULL )
	{
		/* Vytvoreni pomocne promenne */
		tBSTNodePtr tmp = NULL ;

		/* Pokud RootPtr ukazuje na nejpravejsi uzel */
		if ( ( *RootPtr ) -> RPtr == NULL )
		{
			/* Do pomocne priradi ukazatel na nejpravejsi ukazatel */
			tmp = *RootPtr ;

			/* Do uzlu, na ktery ukazuje PtrReplaced, ulozi hodnotu a klic nejpravejsiho uzlu */
			PtrReplaced -> BSTNodeCont = tmp -> BSTNodeCont ;
			PtrReplaced -> Key = tmp -> Key ;

			/* Navazani do stromu */
			*RootPtr = tmp -> LPtr ;

			/* Uvolneni pomocneho ukazatele */
			free ( tmp ) ;
		}

		/* Pokud RootPtr neukazuje na nejpravejsi ukazatel */
		else
		{
			ReplaceByRightmost ( PtrReplaced , ( &( *RootPtr ) -> RPtr ) ) ;
		}
	}
}
Beispiel #6
0
void ReplaceByRightmost (tBSTNodePtr PtrReplaced, tBSTNodePtr *RootPtr) {
/*   ------------------
** Pomocná funkce pro vyhledání, pøesun a uvolnìní nejpravìj¹ího uzlu.
**
** Ukazatel PtrReplaced ukazuje na uzel, do kterého bude pøesunuta hodnota
** nejpravìj¹ího uzlu v podstromu, který je urèen ukazatelem RootPtr.
** Pøedpokládá se, ¾e hodnota ukazatele RootPtr nebude NULL (zajistìte to
** testováním pøed volání této funkce). Tuto funkci implementujte rekurzivnì. 
**
** Tato pomocná funkce bude pou¾ita dále. Ne¾ ji zaènete implementovat,
** pøeètìte si komentáø k funkci BSTDelete(). 
**/
	
	if (*RootPtr != NULL) {
		if ((*RootPtr)->RPtr != NULL) {
			// presunuti se do nejpravejsiho uzlu
			ReplaceByRightmost(PtrReplaced, &(*RootPtr)->RPtr);
		} else {
			// nahrazeni nejpravejsim uzlem
			PtrReplaced->Key = (*RootPtr)->Key;
			PtrReplaced->BSTNodeCont = (*RootPtr)->BSTNodeCont;
			// smazani 
				tBSTNodePtr tmpAddress;
                tmpAddress = (*RootPtr);
				(*RootPtr) = (*RootPtr)->LPtr; 
				free(tmpAddress);
		}
	}		
}
Beispiel #7
0
void BSTDelete (tBSTNodePtr *RootPtr, char K) 		{
/*   ---------
** Zru¹í uzel stromu, který obsahuje klíè K.
**
** Pokud uzel se zadaným klíèem neexistuje, nedìlá funkce nic. 
** Pokud má ru¹ený uzel jen jeden podstrom, pak jej zdìdí otec ru¹eného uzlu.
** Pokud má ru¹ený uzel oba podstromy, pak je ru¹ený uzel nahrazen nejpravìj¹ím
** uzlem levého podstromu. Pozor! Nejpravìj¹í uzel nemusí být listem.
**
** Tuto funkci implementujte rekurzivnì s vyu¾itím døíve deklarované
** pomocné funkce ReplaceByRightmost.
**/
	
	if (*RootPtr != NULL) {
		if ((*RootPtr)->Key == K) {
			// nalezl uzel s klicem K
			if (((*RootPtr)->RPtr != NULL) && ((*RootPtr)->LPtr != NULL)) {
				// ma obadva podstromy
				ReplaceByRightmost((*RootPtr), &(*RootPtr)->LPtr);
			} else if (((*RootPtr)->RPtr != NULL) || ((*RootPtr)->LPtr != NULL)) {
				// ma jeden podstrom
				if ((*RootPtr)->RPtr != NULL) {
					// podstrom je ulozeny jako prava vetev
					tBSTNodePtr tmpAddress;
                    tmpAddress = *RootPtr;
					*RootPtr = (*RootPtr)->RPtr; 
					free(tmpAddress);
				} else {
					// podstrom je ulozeny jako leva vetev
					tBSTNodePtr tmpAddress;
                    tmpAddress = *RootPtr;
					*RootPtr = (*RootPtr)->LPtr; 
					free(tmpAddress);
				}
			} else {
				// nema zadnou vetev
				free(*RootPtr);
				*RootPtr = NULL;
			}
		} else {
			// nenalezl klic, pokracuje v dalsi vetvi
			if (K < (*RootPtr)->Key) {
				BSTDelete(&(*RootPtr)->LPtr, K);
			} else {
				BSTDelete(&(*RootPtr)->RPtr, K);
			}
		}
	} else {
		// neni inicializovany strom
		return;
	}
} 
Beispiel #8
0
void BSTDelete (tBSTNodePtr *RootPtr, char K) {
/* Zru¹í uzel stromu, který obsahuje klíè K. Pokud uzel se zadaným klíèem
** neexistuje, nedìlá nic. Ve¹keré manipulace øe¹te rekurzivnì.
**
** Pokud má ru¹ený uzel jen jeden podstrom, pak jej zdìdí otec. Pokud má
** oba podstromy, pak je ru¹ený uzel nahrazen nejpravìj¹ím uzlem levého
** podstromu. Pozor! Nejpravìj¹í uzel nemusí být listem. Pro tuto operaci
** jsme deklarovali proceduru ReplaceByRightmost -- viz. její komentáø
** uveden vý¹e.
** POZOR: Vzhledem k jisté slo¾itosti rekurzívního volání této fce zde uvádím
** pøíklad jak funkci zavolat (kdy¾ jsme pøijali RootPtr jako ukazatel na 
** ukazatel). Správné zavolání napø. na levý podstrom:
** BSTDelete(&((*RootPtr)->LPtr), K).
** Podobnì je tomu tak i u ReplaceByRightMost().  
** Napøíklad: ReplaceByRightmost(*RootPtr, (&((*RootPtr)->LPtr)))
*/
  tBSTNodePtr ptr;  /* pou¾ívejte tento pomocný ukazatel */
  ptr=NULL;

  if(*RootPtr){
    if((*RootPtr)->Key < K) {
      BSTDelete(&((*RootPtr)->RPtr), K);
    }
    else if((*RootPtr)->Key > K) {
      BSTDelete(&((*RootPtr)->LPtr), K);
    }
    else if((*RootPtr)->Key == K) {
      if((*RootPtr)->LPtr == NULL && (*RootPtr)->RPtr != NULL){
        ptr = (*RootPtr);
        (*RootPtr) = (*RootPtr)->RPtr;
        free(ptr);
      }
      else if((*RootPtr)->RPtr == NULL && (*RootPtr)->LPtr != NULL){
        ptr = (*RootPtr);
        (*RootPtr) = (*RootPtr)->LPtr;
        free(ptr);
      }
      else if ((*RootPtr)->RPtr == NULL && (*RootPtr)->LPtr == NULL){
        free((*RootPtr));
        *RootPtr = NULL;
      }
      else {
        ReplaceByRightmost(*RootPtr, (&((*RootPtr)->LPtr)));
      }
    }
  }
} 
Beispiel #9
0
void BSTDelete (tBSTNodePtr *RootPtr, char K)
{
	if ( *RootPtr != NULL )
	{
		/* Pokud je klic vetsi nez K */
		if ( ( *RootPtr ) -> Key > K )
		{
			/* Pokracuje v levem podstromu */
			BSTDelete ( ( &( *RootPtr ) -> LPtr ) , K ) ;
		}

		/* Pokud je klic mensi nez K */
		else if ( ( *RootPtr ) -> Key < K )
		{
			/* Pokracuje v pravem podstromu */
			BSTDelete ( ( &( *RootPtr ) -> RPtr ) , K ) ;
		}

		/* Pokud najde uzel, ktery se ma rusit */
		else
		{
			/* Vytvoreni pomocne promenne */
			tBSTNodePtr tmp = *RootPtr ;

			/* Pokud uzel nema pravy podstrom */
			if ( ( *RootPtr ) -> RPtr == NULL )
			{
				/* Pripojeni leveho podstromu */
				*RootPtr = ( *RootPtr ) -> LPtr ;
				free ( tmp ) ;
			}

			/* Pokud uzel nema levy podstrom */
			else if ( ( *RootPtr ) -> LPtr == NULL )
			{
				/* Pripojeni praveho podstromu */
				*RootPtr = ( *RootPtr ) -> RPtr ;
				free ( tmp ) ;
			}

			else
			{
				ReplaceByRightmost ( *RootPtr , ( &( *RootPtr ) -> LPtr ) ) ;
			}
		}
	}
} 
Beispiel #10
0
void ReplaceByRightmost (tBSTNodePtr PtrReplaced, tBSTNodePtr *RootPtr) {
/*   ------------------
** Pomocná funkce pro vyhledání, pøesun a uvolnìní nejpravìj¹ího uzlu.
**
** Ukazatel PtrReplaced ukazuje na uzel, do kterého bude pøesunuta hodnota
** nejpravìj¹ího uzlu v podstromu, který je urèen ukazatelem RootPtr.
** Pøedpokládá se, ¾e hodnota ukazatele RootPtr nebude NULL (zajistìte to
** testováním pøed volání této funkce). Tuto funkci implementujte rekurzivnì.
**
** Tato pomocná funkce bude pou¾ita dále. Ne¾ ji zaènete implementovat,
** pøeètìte si komentáø k funkci BSTDelete().
**/
  //nasli jsme nejpravejsi prvek
  if((*RootPtr)->RPtr==NULL){
    tBSTNodePtr ptr=(*RootPtr);
    PtrReplaced->Key=(*RootPtr)->Key;
    PtrReplaced->BSTNodeCont=(*RootPtr)->BSTNodeCont;
    *RootPtr=(*RootPtr)->LPtr;
    free(ptr);
  //zavolame funkci na praveho syna
  }else
    ReplaceByRightmost(PtrReplaced, &((*RootPtr)->RPtr));
}