algorytm.org

Implementacja w C/C++

Baza Wiedzy
wersja offline serwisu przeznaczona na urządzenia z systemem Android
Darowizny
darowiznaWspomóż rozwój serwisu
Nagłówki RSS
Artykuły
Implementacje
Komentarze
Forum
Bookmarki






Sonda
Implementacji w jakim języku programowania poszukujesz?

Drzewa Poszukiwań Binarnych (BST) - Implementacja w C/C++
Ocena użytkownikóww: *****  / 64
SłabyŚwietny
Nadesłany przez Rafał Gawlik, 05 lutego 2012 00:52
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.
Pobierz pełne rozwiązanie.

Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.

bst.c:
//Drzewo BST
//Rafal Gawlik
//www.algorytm.org

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

//definicja wezla
struct wezel
 {
  int wartosc;           //wartosc przechowywana w wezle
  struct wezel *rodzic;  //wskaznik na rodzica
  struct wezel *l_syn;   //wskaznik na lewe dziecko
  struct wezel *p_syn;   //wskaznik na prawe dziecko
 };
struct wezel *root;  //wskaźnik na root'a

//funkcja zwraca wskaznik elementu o najmniejszej wartosci (najbardziej na lewo)
struct wezel* naj_lewo(struct wezel *start)
 {
  if(start->l_syn != NULL)
    return naj_lewo(start->l_syn);
   else
    return start;
 }

//funkcja zwraca wezel o podanej wartosci, badz NULL, gdy taki wezel nie istnieje
struct wezel* szukaj(struct wezel *start, int wartosc)  
 {
   //jezeli wezel ma szukana wartosc to odnalezlismy go
   if (start->wartosc == wartosc) return start;
   //jezeli szukana wartosc jest mniejsza to szukamy w lewym poddrzewie o ile istnieje
   else if (wartosc < start->wartosc && start->l_syn != NULL) return szukaj(start->l_syn, wartosc); 
   //jezeli szukana wartosc jest wieksza to szukamy w prawym poddrzewie o ile istnieje   	
   else if (wartosc > start->wartosc && start->p_syn != NULL) return szukaj(start->p_syn, wartosc);
   return NULL;
 }

//dodaje wezel o podanej wartosci n, do drzewa o korzeniu start
int dodawanie(int n, struct wezel *start)
 {
  //jezeli drzewo jest puste to dodaj korzen
  if (root == NULL)
   {
	root = (wezel*)malloc(sizeof *root);
    root->wartosc = n;
    root->l_syn = NULL;
    root->p_syn = NULL;
    root->rodzic = NULL;
   }
  //jezeli zadana wartosc jest mniejsza od korzenia idz do lewego poddrzewa
  else if(n < start->wartosc)
   {
    //jezeli lewe poddrzewo istnieje wywolaj dla niego ta funkcje rekurencyjnie
    if(start->l_syn != NULL)
     {
      dodawanie(n,start->l_syn);
     }
    //jezeli lewe poddrzewo nie istnieje dodaj nowy wezel o zadanej wartosci
     else
     {
	  wezel *nowy = (wezel*)malloc(sizeof *root);
      nowy->wartosc = n;
      nowy->l_syn = NULL;
      nowy->p_syn = NULL;
      nowy->rodzic = start;
      start->l_syn=nowy;
     }
    }
   //jezeli zadana wartosc jest wieksza lub rowna korzeniowi idz do prawego poddrzewa    
   else
    {
     //jezeli prawe poddrzewo istnieje wywolaj dla niego ta funkcje rekurencyjnie    	
     if(start->p_syn!=NULL)
      {
       dodawanie(n,start->p_syn);
      }
     //jezeli prawe poddrzewo nie istnieje dodaj nowy wezel o zadanej wartosci      
     else
      {
	   wezel *nowy = (wezel*)malloc(sizeof *root);
       nowy->wartosc = n;
       nowy->l_syn = NULL;
       nowy->p_syn = NULL;
       nowy->rodzic = start;
       start->p_syn=nowy;
      }
    }
  return 0;
 }

//usun wezel start
void kasowanie(struct wezel *start)
 {
  //jezeli wezel nie ma dzieci
  if(start->l_syn==NULL && start->p_syn==NULL)
  {
   //jezeli wezel jest korzeniem
   if(start->rodzic==NULL)
   {
    root=NULL;
   }
   //jezeli wezel jest po lewej stronie rodzica,
   else if(start->rodzic->l_syn==start)
   {
    //usun wezel z lewej strony wezla rodzica
    start->rodzic->l_syn=NULL;
   }
   else
   {
    //usun wezel z prawej strony wezla rodzica   	
    start->rodzic->p_syn=NULL;
   }
   delete start;
  }
  //jezeli wezel ma tylko jedno dziecko
  else if(start->l_syn==NULL || start->p_syn==NULL)
  {
   //jezeli po lewej stronie nie ma dziecka
   if(start->l_syn==NULL)
   {
    //jezeli wezel jest korzeniem
    if(start->rodzic==NULL)
    {
     root=start->p_syn;
    }
    //jezeli wezel jest po lewej stronie rodzica
    else if(start->rodzic->l_syn==start)
    {
     //przyczep z lewej strony rodzica wezel bedacy po prawej stronie usuwanego wezla
     start->rodzic->l_syn=start->p_syn;
    }
    else
    {
     //przyczep z prawej strony rodzica wezel bedacy po prawej stronie usuwanego wezla
     start->rodzic->p_syn=start->p_syn;
    }
   }
   else
   {
    //jezeli wezel jest korzeniem
    if(start->rodzic==NULL)
    {
     root=start->l_syn;
    }
    //jezeli wezel jest po lewej stronie rodzica
    else if(start->rodzic->l_syn==start)
    {
     //przyczep z lewej strony rodzica wezel bedacy po lewej stronie usuwanego wezla
     start->rodzic->l_syn=start->l_syn;
    }
    else
    {
     //przyczep z prawej strony rodzica wezel bedacy po prawej stronie usuwanego wezla
     start->rodzic->p_syn=start->l_syn;
    }
   }
   delete start;
  }
  else
  {
   //wstaw w miejsce usuwanego elementu - najmniejsza wartosc z prawego poddrzewa
   struct wezel *temp;
   temp=naj_lewo(start->p_syn);
   start->wartosc = temp->wartosc;
   kasowanie(temp);
  }
 }

//przejdz drzewo w kolejnosci zaczynajac od wezla start
void in_order_tree_walk(struct wezel *start)
 {
  if(start->l_syn != NULL) //jezeli ma dzieci po lewej stronie wywolaj funkcje rekurencyjnie
   in_order_tree_walk(start->l_syn);

  printf("%d\n", start->wartosc); //wypisz wartosc

  if(start->p_syn != NULL) //jezeli ma dzieci po prawej stronie wywolaj rekurencyjnie
   in_order_tree_walk(start->p_syn);
 }

//lsouje wartosc w przedziale od a do b
int losowanie(int a, int b)
 {
  if(a < b)
   return a + (int)((b-a+1.0)*(rand()/(RAND_MAX+1.0)));
  else
  {
   fprintf(stderr, "złe wartości");
   return -1;
  }
 }

//przklad uzycia drzewa BST
int main(int argc, char *argv[])
 {
  int i;
  //pobierz rozmiar drzewa z parametru wejsciowego
  int a,k,size=atoi(argv[1]);
  root = NULL;

  struct timezone tz;
  struct timeval tv;

  gettimeofday(&tv, &tz);
  srand(tv.tv_usec);

  //losuj wartosc elementow
  for(i=0;i<size;i++)
  {
   a=losowanie(1,100);
   dodawanie(a, root);
  }
  printf("\n");
 
  //przejdz drzewo w kolejnosci
  in_order_tree_walk(root);

  //usun wartosc z drzewa
  printf("Wartość węzła do usunięcia: \n");
  scanf("%d", &k);
  kasowanie(szukaj(root,k));
  printf("\n\n");

  //przejdz drzewo w kolejnosci
  in_order_tree_walk(root);

  return 0;
 }
 
Dodaj komentarz