Feladat. Ternáris fa. Típusspecikáció. Reprezentáció. Absztrakt implementáció. Érdi Gerg EAF II. 4/3.

Hasonló dokumentumok
mul : S T N 1 ha t S mul(s, t) := 0 egyébként Keresés Ezt az eljárást a publikus m veletek lenti megvalósításánál használjuk.

Adatszerkezetek 7a. Dr. IványiPéter

Körkörös listák. fej. utolsó. utolsó. fej

Adatszerkezetek és algoritmusok

A lista eleme. mutató rész. adat rész. Listaelem létrehozása. Node Deklarálás. Létrehozás. Az elemet nekünk kell bef zni a listába

Elemi adatszerkezetek

117. AA Megoldó Alfréd AA 117.

... fi. ... fk. 6. Fabejáró algoritmusok Rekurzív preorder bejárás (elsőfiú-testvér ábrázolásra)

INFORMATIKA javítókulcs 2016

Példa 30 14, 22 55,

Algoritmusok és adatszerkezetek gyakorlat 07

Kupac adatszerkezet. A[i] bal fia A[2i] A[i] jobb fia A[2i + 1]

.Net adatstruktúrák. Készítette: Major Péter

Elemi alkalmazások fejlesztése II. 2. Beadandó feladat Juhász Ádám

A feladat lényege egy felhasználói típusnak a zsák típusnak a megvalósítása.

Programozás(A szakirány) II. beadandó feladat Farkas András HP6S15 1. csoport Veszprémi Anna / Hudoba Péter

Objektum elvű alkalmazások fejlesztése. Verem típus osztály-sablonja

A számítástudomány alapjai. Katona Gyula Y. Számítástudományi és Információelméleti Tanszék Budapesti Műszaki és Gazdaságtudományi Egyetem

Információs Technológia

Felhasználó által definiált adattípus

Bevezetés a programozásba Előadás: A const

1. ábra. Egy rekurzív preorder bejárás. Egy másik rekurzív preorder bejárás

Komplex számok. Komplex számok és alakjaik, számolás komplex számokkal.

1. Template (sablon) 1.1. Függvénysablon Függvénysablon példányosítás Osztálysablon

Informatika terméktervezőknek

Programozás II. ATM példa Dr. Iványi Péter

Algoritmusok és adatszerkezetek II.

Bevezetés a programozásba 2

Generikus Típusok, Kollekciók

Programozási Nyelvek: C++

Rendezettminta-fa [2] [2]

C# nyelv alapjai. Krizsán Zoltán 1. Objektumorientált programozás C# alapokon tananyag. Általános Informatikai Tanszék Miskolci Egyetem

Maximum kiválasztás tömbben

1000.AA Megoldo Alfréd 1000.A

Hierarchikus adatszerkezetek

STL gyakorlat C++ Izsó Tamás május 9. Izsó Tamás STL gyakorlat/ 1

Programozás alapjai II. (9. ea) C++ többszörös öröklés, cast, perzisztencia

2. Rekurzió. = 2P2(n,n) 2 < 2P2(n,n) 1

Obudai Egyetem RKK Kar. Feladatok a Matematika I tantárgyhoz

Programozás Minta programterv a 2. házi feladathoz 1.

Collections. Összetett adatstruktúrák

Programozás I. C nyelv

10. előadás Speciális többágú fák

infix kifejezés a+b ab+ +ab postfix kifejezés prefix kifejezés a+b ab+ +ab a+b ab+ +ab Készítette: Szabóné Nacsa Rozália

OAF Gregorics Tibor: Minta dokumentáció a 3. házi feladathoz 1.

Programozás II gyakorlat. 7. Példák a polimorfizmus alkalmazásaira

Bevezetés a programozásba Előadás: Objektumszintű és osztályszintű elemek, hibakezelés

Programozás II gyakorlat. 8. Operátor túlterhelés

7. BINÁRIS FÁK 7.1. A bináris fa absztrakt adattípus 7.2. A bináris fa absztrakt adatszerkezet

Adatszerkezetek és algoritmusok

Fák Témakörök. Fa definíciója. Rekurzív típusok, fa adatszerkezet Bináris keresőfa, bejárások Bináris keresőfa, módosítás B-fa

Fejlett programozási nyelvek C++ Iterátorok

Objektumok inicializálása

OAF Gregorics Tibor: Minta dokumentáció a 4. házi feladathoz 1. Feladat. Megoldás

Algoritmusok és adatszerkezetek II.

Memóriakezelés, dinamikus memóriakezelés

Informatikai Kar. 4. fejezet. Giachetta Roberto

Cekla. Készítette Doxygen Tue Sep :13:44

Statikus adattagok. Statikus adattag inicializálása. Speciális adattagok és tagfüggvények. Általános Informatikai Tanszék

Programozás. C++ osztályok. Fodor Attila. Pannon Egyetem Műszaki Informatikai Kar Villamosmérnöki és Információs Rendszerek Tanszék

Modellezés Gregorics Tibor Mesterséges intelligencia

Elemi alkalmazások fejlesztése III.

Osztály és objektum fogalma

EAF II Feladat dokumentáció IV. feladat 4. házi feladathoz

C++ Standard Template Library (STL)

1. Öröklés Rétegelés Nyilvános öröklés - isa reláció Korlátozó öröklődés - has-a reláció

Programozás II gyakorlat. 4. Öröklődés

Információs Technológia

Objektum elvű alkalmazások fejlesztése Kifejezés lengyel formára hozása és kiértékelése

Java Programozás 1. Gy: Java alapok. Ismétlés ++

Kupac adatszerkezet. 1. ábra.

Tervminták II. (Híd, Bejáró, Gyártófüggvény) Halmaz és bejárása Osztály-sablonok

STL. Algoritmus. Iterátor. Tároló. Elsődleges komponensek: Tárolók Algoritmusok Bejárók

Adatszerkezet - műveletek

C# osztályok. Krizsán Zoltán

Véletlen sorozatok ellenőrzésének módszerei. dolgozat

Bevezetés a C++ programozási nyelvbe

Java és web programozás

sallang avagy Fordítótervezés dióhéjban Sallai Gyula

128. AA Megoldó Alfréd AA 128.

Alkalmazott modul: Programozás 4. előadás. Procedurális programozás: iteratív és rekurzív alprogramok. Alprogramok. Alprogramok.

Challenge Accepted:C++ Standard Template Library

Szoftvertechnolo gia gyakorlat

Programozás. C++ osztályok. Fodor Attila. Pannon Egyetem Műszaki Informatikai Kar Villamosmérnöki és Információs Rendszerek Tanszék

Bevezetés, a C++ osztályok. Pere László

BME MOGI Gépészeti informatika 4.

OOP #14 (referencia-elv)

A programozás alapjai 1 Rekurzió

Objektumorientált programozás C# nyelven

Programozás C++ -ban

Rekurzió. Horváth Gyula.

Programozás I gyakorlat

Objektumorientált programozás C# nyelven III.

MBNK12: Permutációk (el adásvázlat, április 11.) Maróti Miklós

Amortizációs költségelemzés

Online algoritmusok. Algoritmusok és bonyolultságuk. Horváth Bálint március 30. Horváth Bálint Online algoritmusok március 30.

Fejlett programozási nyelvek C++ Sablonok és adatfolyamok

2016, Diszkrét matematika

A szemantikus elemzés helye. A szemantikus elemzés feladatai. A szemantikus elemzés feladatai. Deklarációk és láthatósági szabályok

feladat pont min elért

Átírás:

Feladat djuk meg, hogy egy ternáris fa INORDER bejárás szerint sorozatba f zött értékei között mekkora a leghosszabb csupa pozitív számot tartalmazó részsorozat. Ternáris fa Típusspecikáció z alaphalmaz feletti T 3 ternáris fák halmazát rekurzívan úgy deniálhatjuk, hogy egy ternáris fa vagy üres, vagy egy -beli értékb l, és három (bal, középs, és jobboldali) ternáris fából áll. z elvárható m veletek egyrészt a tárolt értékek elérése és a fa bejárása, másrészt a fa felépítése és módosítása. Reprezentáció ternáris fa egy csúcsát egy t = (k, p, l, m, r) ötös reprezentálja, ahol k a csúcs által tárolt kulcs, p T 3 a szül -csúcs, és l, m, r T 3 a gyermekek. ternáris fát a gyökér-csúcs reprezentálja. bsztrakt implementáció Létrehozás Külön add_root m veletre azért van szükség, hogy megengedjük és kezelni tudjuk az üres fákat. t : tree t := NIL l : l := t == NIL t : add_root(t, k) new(t) t.k := k t.p, t.l, t.m, t.r := NIL, NIL, NIL, NIL Navigáció t : left(t) HIB t := t.l t : middle(t) HIB t := t.m t : right(t) HIB t := t.r l : left?(t) l : middle?(t) l : right?(t) HIB t.p NIL left(t.p) = t l := l := HIB t.p NIL middle(t.p) = t l := l := HIB t.p NIL right(t.p) = t l := l :=

Feltöltés t : add_left(t, k) left(t) NIL new(t ) t.k := k HIB t.p, t.l, t.m, t.r := t, NIL, NIL, NIL t.l := t add_middle, add_right értelemszer en. Bejárás fa bejárásait a callback pattern modellezésével végezzük. Ebben a modellben a φ callback kétváltozós, egyértek függvényként jelenik meg, ahol a második változó, és az érték, a callback állapotát jelenti: φ : S φ S φ Így egyszer en adódnak a bejáró eljárások rekurzív deníciói: s : preorder(t, φ, s 0 ) s : postorder(t, φ, s 0 ) s := s 0 s := s 0 s := φ(t.k, s) s : postorder(left(t), φ, s) SKIP s : preorder(left(t), φ, s) s : preorder(middle(t), φ, s) SKIP s : postorder(middle(t), φ, s) s : postorder(right(t), φ, s) s : preorder(right(t), φ, s) s := φ(t.k, s) s : inorder(t, φ, s 0 ) s := s 0 s : inorder(left(t), φ, s) SKIP s := φ(t.k, s) s : inorder(middle(t), φ, s) s : inorder(right(t), φ, s)

Véletlenszer ternáris fa felépítése feladat megoldását véletlenszer en generált ternáris fákon fogjuk bemutatni. Ehhez szükségünk lesz az alábbi programra, amely a megadott ternáris fán egy véletlenszer útvonalon eljut egy levélig, és annak egy véletlenszer helyére berakja a kapott elemet. random_insert(t, k) add_root(t, k) d = t := left(t ) d = add_left(t, k) t = NIL t := t d := random,, d = isempty(left(t )) d = isempty(middle(t )) d = isempty(right(t )) d = t := middle(t ) d := random,, d = add_middle(t, k) t : random_tree t : tree n : random(n + ) n > 0 random_insert(t, random()) n := n 1 d = t := right(t ) d = add_right(t, k) Leghosszabb részsorozat hossza z eddigi eredményeink alapján tehát a feladatot visszavezettük a fent deniált inorder eljárás alkalmas φ függvénnyel való alkalmazására. Ehhez tekintsük az alábbi függvénydeníciót: φ π : N N N N (m, 0) ha π(k) φ π (k, m, c) := (m, c + 1) ha π(k) c + 1 m (c + 1, c + 1) ha π(k) c + 1 > m

Ezt könnyedén implementálhatjuk lényegében a feltételes maximumkeresés tételének hasával: m, c : φ π (k, m, c) π(k) c := c + 1 c > m c := 0 m := c SKIP És így a feladat megoldása el áll a következ programmal: m : longest_positive_seq_len(t) m, c : inorder(t, φ x>0, (0, 0))

C++ implementáció Referenciaszálálásos smartpointer z egyetlen nehézséget az implementációban az adja, hogy a fenti modell megvalósításához a fákat referencia szerint kell átadni, ami megnehezíti a memóriakezelést. Ezért egy nagyon egyszer, referenciaszámlálásos smartpointert fogunk használni: template<typename T> c l a s s RefCountedPtr T p t r ; mutable unsigned int r e f c o u n t ; RefCountedPtr (T ptr_ = 0) : p t r ( ptr_ ), r e f c o u n t (new unsigned int ( 1 ) ) RefCountedPtr ( const RefCountedPtr<T> &o t h e r ) : p t r ( o t h e r. p t r ), r e f c o u n t ( o t h e r. r e f c o u n t ) ++ r e f c o u n t ; ~RefCountedPtr ( ) d i s p o s e ( ) ; T const operator > ( ) return p t r ; const T const operator > ( ) const return p t r ; operator bool ( ) const return p t r ; bool operator== ( const RefCountedPtr<T> &o t h e r ) const return o t h e r. p t r == p t r ; RefCountedPtr<T> &operator= ( const RefCountedPtr<T> &o t h e r ) i f ( o t h e r. p t r == p t r ) return this ; d i s p o s e ( ) ; p t r = o t h e r. p t r ; r e f c o u n t = o t h e r. r e f c o u n t ; r e f c o u n t += 1 ; return this ; private : void d i s p o s e ( ) i f (! r e f c o u n t ) delete p t r ; delete r e f c o u n t ; ;

Ternáris fa template<typename T> c l a s s TernaryTree lapm veletek fenti smartpointerrel már egyszer en megvalósíthatóak az alapm veletek: struct TreeNode T key ; RefCountedPtr<TreeNode> p a r e n t ; RefCountedPtr<TreeNode> l e f t, middle, r i g h t ; TreeNode ( RefCountedPtr<TreeNode> parent_, const T &key_ ) : key ( key_ ), p a r e n t ( parent_ ) ; ~TreeNode ( ) RefCountedPtr<TreeNode> node ; TernaryTree ( RefCountedPtr<TreeNode> node_ ) : node ( node_ ) TernaryTree ( ) TernaryTree ( const T &root_key ) : node (new TreeNode ( 0, root_key ) ) TernaryTree ( const TernaryTree<T> &o t h e r ) : node ( o t h e r. node ) operator bool ( ) const return node!= 0 ; const T& get_key ( ) const return node >key ; T& set_key ( const T &key ) a s s e r t ( node ) ; return node >key = key ; Navigáció TernaryTree p a r e n t ( ) const return node >p a r e n t ; TernaryTree l e f t ( ) const return node > l e f t ; TernaryTree middle ( ) const return node >middle ; TernaryTree r i g h t ( ) const return node >r i g h t ; bool i s _ r o o t ( ) const return! node >p a r e n t ; bool i s _ l e f t ( ) const return node >p a r e n t && node >parent > l e f t == node ; bool is_ middle ( ) const return node >p a r e n t && node >parent >middle == node ; bool i s _ r i g h t ( ) const return node >p a r e n t && node >parent >r i g h t == node ;

Felépítés Bejárás void add_root ( const T &key = T( ) ) a s s e r t (! node ) ; node = new TreeNode ( 0, key ) ; TernaryTree a d d _ l e f t ( const T &key = T ( ) ) a s s e r t ( node &&! node > l e f t ) ; return node >l e f t = new TreeNode ( node, key ) ; TernaryTree add_middle ( const T &key = T ( ) ) a s s e r t ( node &&! node >middle ) ; return node >middle = new TreeNode ( node, key ) ; TernaryTree add_right ( const T &key = T ( ) ) a s s e r t ( node &&! node >r i g h t ) ; return node >r i g h t = new TreeNode ( node, key ) ; bejárást természetesen nem szigorúan a modellt követve valósítjuk meg, hanem a szokásos callback patternt követve: class v i s i t o r virtual ~ v i s i t o r ( ) ; ; virtual void v i s i t _ n o d e ( TernaryTree<T> &t r e e ) = 0 ; void v i s i t _ i n o r d e r ( v i s i t o r &v i s i t o r ) i f (! this ) return ; l e f t ( ). v i s i t _ i n o r d e r ( v i s i t o r ) ; v i s i t o r. v i s i t _ n o d e ( this ) ; middle ( ). v i s i t _ i n o r d e r ( v i s i t o r ) ; r i g h t ( ). v i s i t _ i n o r d e r ( v i s i t o r ) ;

Véletlen fa felépítése void insert_random_node ( TernaryTree<T> t r e e, const T &v a l u e ) i f (! t r e e ) t r e e. add_root ( v a l u e ) ; else int d = random ( ) % 3 ; while ( ( d == 0 && t r e e. l e f t ( ) ) ( d == 1 && t r e e. middle ( ) ) d == 2 && t r e e. r i g h t ( i f ( d == 0) t r e e = t r e e. l e f t ( ) ; else i f ( d == 1) t r e e = t r e e. middle ( ) ; else t r e e = t r e e. r i g h t ( ) ; d = random ( ) % 3 ; i f ( d == 0) t r e e. a d d _ l e f t ( v a l u e ) ; else i f ( d == 1) t r e e. add_middle ( v a l u e ) ; else t r e e. add_right ( v a l u e ) ; TernaryTree<int> random_tree ( ) srandom ( time ( 0 ) ) ; unsigned int nodes_num = random ( ) % 20 + 5 ; TernaryTree<int> t r e e ; t r e e. add_root ( ( random ( ) >> 5) % 200 1 0 0 ) ; for ( unsigned int i = 1 ; i!= nodes_num ; ++i ) int v a l u e = ( random ( ) >> 5) % 200 1 0 0 ; insert_random_node ( t r e e, v a l u e ) ; return t r e e ;

feladatot megoldó callback class L o n g e s t I n o r d e r P o s i t i v e S e q u e n c e L e n : public TernaryTree<int > : : c o n s t _ v i s i t o r unsigned int count ; unsigned int max_count ; L o n g e s t I n o r d e r P o s i t i v e S e q u e n c e L e n ( ) : count ( 0 ), max_count ( 0 ) void v i s i t _ n o d e ( const TernaryTree<int> &t r e e ) i f ( t r e e. get_key ( ) > 0) i f (++count > max_count ) max_count = count ; else count = 0 ; ; unsigned int r e s u l t ( ) const return max_count ; template<typename T> int l o n g e s t _ i n o r d e r _ p o s i t i v e _ s e q u e n c e _ l e n ( const TernaryTree<T> &t r e e ) L o n g e s t I n o r d e r P o s i t i v e S e q u e n c e L e n v i s i t o r ; t r e e. v i s i t _ i n o r d e r ( v i s i t o r ) ; return v i s i t o r. r e s u l t ( ) ;