Przeszukiwanie drzewa

0

Witam Wszystkich.
Mam dziwny problem z funkcją przeszukującą drzewo metodą preorder

type
    PInod = ^ TInod;
    TInod = record
    wartosc : string;
    gora  :PInod;
    lewo :PInod;
    prawo:PInod;
    end;
var
    Inod : PInod;
    S : String;
function szukaj( var Tree : PInod ;S : string):PInod;
 begin
 if Tree.wartosc = S then szukaj := Tree
        else
        begin
        if Tree.lewo <> nil then szukaj:= szukaj(Tree.lewo , S );
        if Tree.prawo <> nil then szukaj := szukaj( Tree.prawo , S );
        end;
 end;

w programie funkcja jest wywoływana :

Inod := szukaj(Inod, S);

I wszystko działa prawidłowo , jednak ja potrzebuję aby wartosc była typu byte ( lub ShortInt ) ale po zmianie typu czyli :

type
    PInod = ^ TInod;
    TInod = record
    wartosc : byte;
    gora  :PInod;
    lewo :PInod;
    prawo:PInod;
    end;
var
    Inod : PInod;
    S : byte;
function szukaj( var Tree : PInod ;S : byte):PInod;
 begin
 if Tree.wartosc = S then szukaj := Tree
        else
        begin
        if Tree.lewo <> nil then szukaj:= szukaj(Tree.lewo , S );
        if Tree.prawo <> nil then szukaj := szukaj( Tree.prawo , S );
        end;
 end;

funkcja przestaje działać i zwraca jako wskaznik przypadkową wartość , dodam , że w obu przypadkach nie ma błędu przy kompilacji .
Gdzie tkwi problem ?
Wielkie dzięki za jakąkolwiek odpowiedź .

0

Witaj,

Ja w swojej pracy nauczylem sie, ze zycie sklada sie z kompromisow.

Jesli nie dziala ci na "Byte", zrob to na "Integer" - to jest zreszta najszybsze. Jesli zas chcesz koniecznie miec wynik koncowy jako "Byte" to po prostu skonwertuj to do bajtu po przeszukaniu drzewa.

Oczywisicie moznaby by w koncu wziac to pod mikroskop i analizujac - wykryc blad. Ale ja pisac rozne rzeczy (kiedys byla to np. Amiga, z jego asemblerem, a potem kilo innych rzeczy) - nauczylem sie, ze szkoda czasu .

Jest pewien kompromis pomiedzy uzyskanym rezultatem, a korzysciami. (np. finansowymi). I nie tylko chodzi tu o to, ze czas to pieniadz, albo masz termin na wczoraj, ale w moim przypadku, po napisaniu setek tysiecy linii kodu w roznych jezykach - wyksztalcilo sie cos na ksztalt rutyny polaczonej z lenistwem. Juz mi sie nie chce.

A zaoszczedzony na tym czas poswiecam teraz na ciekawe spotkania z z ludzmi w realu, czy z pewna panna; ostatnio mialem tez fajny wypad za miasto z ludzmi z kregu czcicieli musyki elektronicznej.

Wiec moja rada taka: poswiec na znalezienie bledu troche czasu, ale nie rob tego jesli widzisz, ze w rozsadnym czasie nic sie nie klei. Zastosuj skrot lub napisz kod od nowa.

0

Dzięki za próbę pomocy jednak funkcja działa tylko i wyłącznie ze zmienną typu string , jakakolwiek inna ( byte , shortint , word , smallint, longword , integer , int64 ) niestety nie działa .
Właściwie to chodzi mi bardziej dlaczego tak się dzieje , przecież typ zmiennej przechowywanej w rekordzie nie powinien teoretycznie mieć wpływu na działanie funkcji , która jedynie porównuje wartość tej zmiennej z inną tego samego typu .

0

Witam ponownie .
Znalazłem częściowe rozwiązanie mojego problemu , za radą JKoala22 postanowiłem napisać to tak samo tylko inaczej i powstało to :

procedure znajdz(var Tree : PInod ; S : byte );
begin
if tree.znak = S then Inod := Tree
    else
    begin
    if tree.lewo <> nil then znajdz(tree.lewo , S);
    if tree.prawo <> nil then znajdz(tree.prawo , S);
    end;
end;

Jest to jednak tylko częściowe rozwiązanie na potrzeby obecnie pisanego programu , gdyż pomimo iż działa prawidłowo procedura operuje na zmiennej globalnej Inod , wiec dla każdej zmiennej typu PInod musi istnieć osobna procedura .
W dalszym ciągu oczekuję jakiejś odpowiedzi dlaczego w przeciwieństwie do procedury funkcja nie działa dla zmiennych typu byte ?

0
if tree^.wartosc = ...

?

0

Niestety nie.

Inod.wartosc

oraz

Inod^.wartosc

to dokładnie to samo.

0
function szukaj( var Tree : PInod ;S : byte):PInod;
 begin
 if Tree.wartosc = S then szukaj := Tree
        else
        begin
        {1}if Tree.lewo <> nil then szukaj:= szukaj(Tree.lewo , S );
        {2}if Tree.prawo <> nil then szukaj := szukaj( Tree.prawo , S );
        end;
 end;

załóżmy że wykonanie jest w węźle który się rozgałęzia i od którego rozwiązanie jest na lewo, a na prawo go nie ma.
po wykonaniu linijki {1} wynik mamy w szukaj.
ale chwile potem wykonujemy linijkę {2} która zamazuje uzyskany przed chwilą wynik przypadkową wartością.
najłatwiej temu zradzić przekazując referencję do zmiennej

procedure proc_szukaj( var Wynik, Tree : PInod; S : byte);
 begin// zwroci ostatnio znaleziony wezel
 if Tree.wartosc = S then Wynik := Tree
        else
        begin
        if Tree.lewo <> nil then  proc_szukaj( Wynik, Tree.lewo , S );
        if Tree.prawo <> nil then proc_szukaj( Wynik, Tree.prawo , S );
        end;
 end;

wykorzystanie

  
   Wynik:=nil;
   proc_szukaj( Wynik, Inod, szukanyBajt );
   if Wynik=nil then
      //nie znaleziono
   else
     //znaleziono

jeśli konieczne jest użycie funkcji to może być coś takiego

function szukaj( var Tree : PInod ;S : Byte):PInod;
 var// zwroci pierwszy znaleziony wezel
   lszukaj: PInod;
 begin
   szukaj:=nil;
   if Tree.wartosc = S then
     szukaj := Tree
   else
     begin
       if Tree.lewo <> nil then
         begin
           lszukaj:= szukaj(Tree.lewo , S );
           szukaj:=lszukaj;
           if lszukaj=nil then
             if Tree.prawo <> nil then
               szukaj := szukaj( Tree.prawo , S );
         end;
     end;
 end;
0

Wielkie dzięki TuNadlatujoncyQbek widać , że znasz się na rzeczy .

Ja jednak z uporem maniaka będę dociekał dlaczego moja wersja funkcjii działa tylko dla zmiennych typu string . Czy jest to jakiś szczególny przypadek , dla którego błędnie sformułowana funkcja działa prawidłowo , czy może jakaś luka albo jeszcze coś innego . Jak tylko coś znajdę dam znać .
Pozdro .

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