drzewo binarne

0

witam, mam problem z drzewem binarnym. Napisalem funkcje dodajaca kolejny wezel do takiego drzewa i chchcialem ja przetestowac, ale niestety program wysypuje sie - co ciekawe tylko wtedy, kiedy chce dodac liczbe mniejsza niz ta znajdujaca sie w korzeniu - jesli dodaje wieksza to wszystko jest ok. Niestety nie moge znaleŹĆ bledu, bede zobowiaznay za pomoc

 class wezel {
      private:
              wezel *lewy;   //wskaznik na lewy wezel (mniejszy)
              wezel *prawy;  //wskaznik na prawy wezel (wiekszy)
              wezel *rodzic; //wskaznik na rodzica
              int wartosc;   //wartosc
              friend class drzewo;
      public:
              void Wyzeruj() { lewy=prawy=NULL;} ;  
              int Wez() {return wartosc;};           
      };

class drzewo {
      private: 
                   
              wezel *korzen;  //wskaznik na korzen drzewa
              int licznik;        //zlicza ilosc elementow
      public:
             void Wyzeruj();
             int Dodaj(const int a);
             wezel* ZwrocKorzen() { return korzen;} ;
             void druk(wezel*t,int h);
      };

//konstuktor drzewa  
void drzewo:: Wyzeruj()
{
         korzen = NULL;
         licznik = 0;
}
    
    
int drzewo:: Dodaj(const int a)
{
     wezel *nowy;
     nowy = new wezel;
     nowy -> wartosc = a;
     nowy -> lewy = NULL;
     nowy -> prawy = NULL;
     nowy -> rodzic = NULL;
     nowy->Wyzeruj();
     if (licznik==0)
     {
        //gdy licznik jest zerem wstawiany wezel bezie korzeniem
        //wiec jego rodzic to nulll
        korzen = nowy;
        licznik++;    
        return 0;
     }
     else
     {   /*wskazik miejsce bedzie przebiegal sciezke w dol drzewa, na poczatku
         wskazuje na korzen*/
         wezel *miejsce = korzen;
         /*rodzic miejsce wskazuje a rodzica miejsca, czyli poczatkowo na NULL*/
         wezel *rodzic_miejsca;
         //petla wykonuje sie dopoki miejsce nie jest wskaznikiem na zero 
         while(miejsce != NULL)
         {
                       
               cout<<miejsce->wartosc<<endl;
               rodzic_miejsca = miejsce;
               if(a <  miejsce->wartosc)
               {
                    cout<<"AA"<<endl;
                    miejsce = miejsce->lewy;
                    cout<<"BB"<<endl;
               }
               if (a > miejsce->wartosc)
               {
                     miejsce = miejsce ->prawy;
               }
               
         }
         cout <<rodzic_miejsca->wartosc<<endl;
         if ( a < rodzic_miejsca->wartosc)
         { 
              cout<<"1 !"<<endl;
              rodzic_miejsca->lewy = nowy;
              nowy -> rodzic = rodzic_miejsca;
              licznik++;
              return 0;
         }
         if ( a > rodzic_miejsca->wartosc)
         {
              rodzic_miejsca->prawy = nowy;
              nowy -> rodzic = rodzic_miejsca;
              licznik++;
              return 0;
         }
     }
     //jesli funkcja zwroci -1, to znaczy ze wezel o wartosci ktora chcemy dodac
     //znajduje sie juz na drzewie
    // return -1; 
}
0
  1. Rada generalna, może zacznij od rzeczy prostych dopóki nie zrozumiesz generalnych zasad programowania obiektowego.
  2. Nie używaj takich dziwactw jak Wyzeruj() (to nie jest konstruktor) utwórz konstruktory domyślny i kupujący oraz destruktor.
  3. Nie używaj wartości int kiedy potrzebujesz wartości bool.
  4. Zapomniałeś zwolnić węzeł jeżeli taki już jest w drzewie.
  5. Węzeł lepiej zrobić jako klasę wewnętrzną.
  6. Nawet dla węzła przydaje się konstruktor.
    Analiza jak naprawić to co podałeś zajmie więcej czasu niż napisanie od nowa :-D
#include <iostream>
using namespace std;

#define DRZEWIASTY_DRUK

class drzewo
  {
   private:
   class wezel
     {
      private:
      wezel *lewy;
      wezel *prawy;
      wezel *rodzic;
      int wartosc;
      wezel(int wartosc,wezel *rodzic):lewy(0),prawy(0),rodzic(rodzic),wartosc(wartosc) {}
      public:
      wezel *Lewy()const { return lewy; }
      wezel *Prawy()const { return prawy; }
      wezel *Rodzic()const { return rodzic; }
      int Wartosc()const { return wartosc; };
      friend class drzewo;
     };
   wezel *korzen;
   static void _zwolnij(wezel *tmp);
   void _druk(ostream &s,const wezel *tmp)const;
   public:
   drzewo():korzen(0) {}
   ~drzewo() { if(korzen) _zwolnij(korzen); }
   bool Dodaj(int wartosc);
   drzewo &operator<<(int wartosc) { Dodaj(wartosc); return *this; }
   wezel *Korzen()const { return korzen; }
   ostream &druk(ostream &s)const { if(korzen) _druk(s,korzen); return s; }
  };
ostream &operator<<(ostream &s,const drzewo &d) { return d.druk(s); }
 
void drzewo::_zwolnij(wezel *tmp)
  {
   if(tmp->lewy) _zwolnij(tmp->lewy);
   if(tmp->prawy) _zwolnij(tmp->prawy);
   delete tmp;
  }

void drzewo::_druk(ostream &s,const wezel *tmp)const
  {
   if(tmp->lewy) _druk(s,tmp->lewy);
#ifdef DRZEWIASTY_DRUK
   int wartosc=tmp->wartosc;
   const wezel *p=korzen,*c;
   for(int pv=0,v=1;p;p=c,pv=v)
     {
      int pwartosc=p->wartosc;
      if(wartosc<pwartosc)      { v=-1; c=p->lewy;  }
      else if(wartosc>pwartosc) { v=+1; c=p->prawy; }
      else                      { v=0;  c=0;        }
      if(p!=korzen) s<<(v?(v!=pv?"\xB3  ":"   "):(pv<0?"\xDA\xC4\xC4":"\xC0\xC4\xC4"));
     }
   s<<'\xDB'<<' '<<wartosc<<endl;
#else
   s<<tmp->wartosc<<' ';
#endif
   if(tmp->prawy) _druk(s,tmp->prawy);
  }

bool drzewo::Dodaj(int wartosc)
  {
   wezel *rodzic=0,*tmp=korzen;
   int V=0;
   while(tmp)
     {
      rodzic=tmp;
      if(tmp->wartosc>wartosc) { V=-1; tmp=rodzic->lewy; }
      else if(tmp->wartosc<wartosc) { V=1; tmp=rodzic->prawy; }
      else return false;
     }
   (V?(V>0?rodzic->prawy:rodzic->lewy):korzen)=new wezel(wartosc,rodzic);
   // ewentualnie tu zwiększasz licznik
   return true;
  }

int main()
  {
   drzewo d;
   d<<4<<2<<6<<1<<3<<5<<7;
   cout<<d<<endl;
   if(!d.Dodaj(1)) cout<<"wartosc 1 juz jest"<<endl<<endl;
   if(!d.Dodaj(0)) cout<<"wartosc 0 juz jest"<<endl<<endl;
   cout<<d<<endl;
   cin.sync();
   cin.get();
   return 0;
  }
0

Wielkie dzieki za pomoc!
Funkcja drukuj to niestety totalnie czarna magia..mozesz pokac, co w niej zmienic aby element mniejszy dodawal na lewo, a wiekszy na prawo? (obecnie wyswietla odwrotnie)

1 użytkowników online, w tym zalogowanych: 0, gości: 1