Moeki Geschrieben 21. Januar 2007 Teilen Geschrieben 21. Januar 2007 Moin Moin. Im Rahmen eines Aufgabe an der Uni, stoße ich langsam aber sicher an meine Grenzen. Die Aufgabe ist, einen in einer Tabelle gespeicherten binbären Baum in PREORDER, INORDER, POSTORDER und LEVELORDER Reihenfolge auszugeben und die Werte in eine Tabelle zu speichern. Die Proceduren sollen iterativ sein. Um, die Werte in eine Tabelle zu speichern brauche ich Container. Ich habe diverse Varianten probiert, scheitere jetzt aber an Compilierungsfehler bei der Typdeklaration. Warning: Type created with compilation errors. Wie kann ich die ausmerzen, "show" funktioniert leider nicht. Bzw. vielleicht findet ihr bei beim Überfliegen den Fehler. Ich weiß, dass die unterschiedlichen Typen für Stack und Queue nicht unbedingt ideal sind, kann das aber nicht anders im Moment. SET SERVEROUTPUT ON; EXEC DBMS_OUTPUT.ENABLE(200000); DROP TABLE RESULT PURGE; CREATE TABLE result (preord number(12), inord number(12), postord number(12), levelord number(12)); CREATE OR REPLACE TYPE con_type IS TABLE OF number(12); ------------------------------------- DECLARE con_pre con_type := con_type(); con_in con_type := con_type(); con_post con_type := con_type(); con_level con_type := con_type(); TYPE mein_typ IS RECORD(lfd number(12)); TYPE my_queue IS TABLE OF mein_typ INDEX BY BINARY_INTEGER; queue my_queue; TYPE my_type IS TABLE OF number(12) INDEX BY BINARY_INTEGER; stack my_type; -- Get Funktion definiert auf Queue vom Typ my_type FUNCTION get RETURN mein_typ IS merk mein_typ; BEGIN merk := queue(queue.first); queue.delete(queue.first); return merk; END; -- Put Procedur definiert auf Queue vom Typ my_type PROCEDURE put(lfd IN number) is BEGIN IF (queue.exists(queue.last)) THEN queue(queue.last+1).lfd := lfd; ELSE queue(1).lfd := lfd; END IF; END; --Push Procedur definiert auf Stack vom Typ my_type PROCEDURE push(in_stack IN number) is BEGIN IF (stack.exists(stack.last)) THEN stack(stack.last+1) := in_stack; ELSE stack(1) := in_stack; END IF; END; --Pop Funktion definiert auf Stack vom Typ my_type FUNCTION pop RETURN number IS merk number(12); BEGIN merk := stack(stack.last); stack.delete(stack.last); return merk; END; --Topstack Funktion definiert auf Stack vom Typ my_type FUNCTION topstack RETURN number IS BEGIN return stack(stack.last); END; --Preorder Traversierung PROCEDURE preorder (akt IN number) IS li number(12); re number(12); cur number(12); CURSOR c1(aktuell IN NUMBER) IS SELECT links, rechts FROM verbindung WHERE (aktuell = lfd); BEGIN push(akt); WHILE (topstack() IS NOT NULL) LOOP cur:=pop(); OPEN c1(cur); FETCH c1 INTO li,re; CLOSE c1; IF (cur IS NOT NULL) THEN BEGIN IF (con_pre.exists(con_pre.last)) THEN BEGIN con_pre.extend; con_pre(con_pre.last) := cur; END; ELSE BEGIN con_pre.extend; con_pre(1) := cur;END; END IF; END; END IF; push(re); push(li); END LOOP; END; --Inorder Traversierung PROCEDURE inorder (akt IN number) IS li number(12); re number(12); cur number(12); CURSOR c1(aktuell IN NUMBER) IS SELECT links, rechts FROM verbindung WHERE (aktuell = lfd); BEGIN OPEN c1(akt); FETCH c1 INTO li,re; CLOSE c1; push(li); WHILE (topstack() IS NOT NULL) LOOP cur:=pop(); OPEN c1(cur); FETCH c1 INTO li,re; CLOSE c1; IF (cur IS NOT NULL) THEN BEGIN IF (con_in.exists(con_in.last)) THEN BEGIN con_in.extend; con_in(con_in.last) := cur; END; ELSE BEGIN con_in.extend; con_in(1) := cur;END; END IF; END; END IF; push(re); push(cur); END LOOP; END; --Postorder Traversierung PROCEDURE postorder (akt IN number) IS li number(12); re number(12); cur number(12); CURSOR c1(aktuell IN NUMBER) IS SELECT links, rechts FROM verbindung WHERE (aktuell = lfd); BEGIN OPEN c1(akt); FETCH c1 INTO li,re; CLOSE c1; push(li); WHILE (topstack() IS NOT NULL) LOOP cur:=pop(); OPEN c1(cur); FETCH c1 INTO li,re; CLOSE c1; IF (cur IS NOT NULL) THEN BEGIN IF (con_post.exists(con_post.last)) THEN BEGIN con_post.extend; con_post(con_post.last) := cur; END; ELSE BEGIN con_post.extend; con_post(1) := cur;END; END IF; END; END IF; push(cur); push(re); END LOOP; END; --Levelorder Traversierung PROCEDURE levelorder(akt IN number) IS k1 mein_typ; li number(12); re number(12); cur number(12); CURSOR c1(akt IN number) IS SELECT links, rechts FROM verbindung WHERE (akt = lfd); BEGIN put(akt); con_level.extend; con_level(1) := akt; WHILE (queue.exists(queue.first)) LOOP k1 := get(); dbms_output.put_line(k1.lfd); OPEN c1(k1.lfd); FETCH c1 INTO li, re; CLOSE c1; IF (li IS NOT NULL) THEN BEGIN con_level.extend; con_level(con_level.last) := li; put(li); END; END IF; IF (re IS NOT NULL) THEN BEGIN con_level.extend; con_level(con_level.last) := re; put(re); END; END IF; END LOOP; END; -- main BEGIN inorder(13); preorder(13); postorder(13); levelorder(13); forall i in indices of con_pre insert into result values(con_pre(I),con_in(I),con_post(I),con_level(I)); END; / select * from result; Gruß, Moeki.Kopie von traversierung_3.sql.txt Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
mme Geschrieben 22. Januar 2007 Teilen Geschrieben 22. Januar 2007 Hallo, ich kenne das nur so das du entweder create type con_type as object (test number(12)); angibst oder du erstellst einen Type und bindest diesen Type dann als Table in den anderen Type ein: create type con_type_innen as object (test number(12)); CREATE TYPE con_type IS TABLE OF con_type_innen; Ansonsten schön das du den ganzen Code postest, aber wenn du der Fehler schon kommt beim erzeugen des Types brauchst du den anonymen Block nicht angeben. Wobei ich auf einen anonymen Block grundsätzlich verzichten würde (wenn möglich). Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Moeki Geschrieben 29. Januar 2007 Autor Teilen Geschrieben 29. Januar 2007 Hat sich erledigt :-) Nun habe ich mein Programme, dass bestimmte Prozeduren aufruft, Tabellen und Typen erstellt und eine Ausgabe in eine Tabelle schreibt. Alles das möchte ich nun anderen in Form einer Prozedur oder eines Packages zur Verfügung stellen. Geht das hier überhaupt? Welches wäre die bessere Strategie? Gruß, Moeki. SET SERVEROUTPUT ON; EXEC DBMS_OUTPUT.ENABLE(200000); DROP TABLE besucht_post PURGE; DROP TABLE result PURGE; DROP TYPE con_type FORCE; CREATE OR REPLACE TYPE con_type IS TABLE OF number(12); / CREATE TABLE result (preord number(12), inord number(12), postord number(12), levelord number(12)); CREATE TABLE besucht_post(lfd number(2), links number(2), rechts number(2)); ------------------------------------- DECLARE con_pre con_type := con_type(); con_in con_type := con_type(); con_post con_type := con_type(); con_level con_type := con_type(); TYPE mein_typ IS RECORD(lfd number(12)); TYPE my_queue IS TABLE OF mein_typ INDEX BY BINARY_INTEGER; queue my_queue; TYPE my_type IS TABLE OF number(12) INDEX BY BINARY_INTEGER; stack my_type; -- Get Funktion definiert auf Queue vom Typ my_type FUNCTION get RETURN mein_typ IS merk mein_typ; BEGIN merk := queue(queue.first); queue.delete(queue.first); return merk; END; -- Put Procedur definiert auf Queue vom Typ my_type PROCEDURE put(lfd IN number) is BEGIN IF (queue.exists(queue.last)) THEN queue(queue.last+1).lfd := lfd; ELSE queue(1).lfd := lfd; END IF; END; --Push Procedur definiert auf Stack vom Typ my_type PROCEDURE push(in_stack IN number) is BEGIN IF (stack.exists(stack.last)) THEN stack(stack.last+1) := in_stack; ELSE stack(1) := in_stack; END IF; END; --Pop Funktion definiert auf Stack vom Typ my_type FUNCTION pop RETURN number IS merk number(12); BEGIN merk := stack(stack.last); stack.delete(stack.last); return merk; END; --Topstack Funktion definiert auf Stack vom Typ my_type FUNCTION topstack RETURN number IS BEGIN return stack(stack.last); END; --IsEmpty Funktion definiert auf Stack vom Typ my_type FUNCTION is_empty RETURN boolean IS empty boolean; BEGIN IF stack.exists(stack.last) THEN empty:=FALSE; ELSE empty:=TRUE; END IF; return empty; END; --Preorder Traversierung PROCEDURE preorder (akt IN number) IS li number(12); re number(12); cur number(12); CURSOR c1(aktuell IN NUMBER) IS SELECT links, rechts FROM verbindung WHERE (aktuell = lfd); BEGIN dbms_output.put_line('PREORDER'); IF (akt IS NOT NULL) THEN push(akt); END IF; WHILE NOT is_empty LOOP cur:=pop(); dbms_output.put_line(cur); OPEN c1(cur); FETCH c1 INTO li,re; CLOSE c1; IF (con_pre.exists(con_pre.last)) THEN BEGIN con_pre.extend; con_pre(con_pre.last) := cur; END; ELSE BEGIN con_pre.extend; con_pre(1) := cur; END; END IF; IF (re IS NOT NULL) THEN push(re); END IF; IF (li IS NOT NULL) THEN push(li); END IF; END LOOP; END; --Inorder Traversierung PROCEDURE inorder (akt IN number) IS done boolean:=false; li number(12); re number(12); cur number(12); CURSOR c1(aktuell IN NUMBER) IS SELECT links, rechts FROM verbindung WHERE (aktuell = lfd); BEGIN cur:=akt; IF (cur IS NOT NULL) THEN push(cur); END IF; dbms_output.put_line('INORDER'); WHILE (cur IS NOT NULL) AND NOT is_empty LOOP LOOP OPEN c1(cur); FETCH c1 INTO li,re; CLOSE c1; push(cur); cur:=li; EXIT WHEN (cur IS NULL); END LOOP; cur:=pop(); dbms_output.put_line(cur); IF (con_in.exists(con_in.last)) THEN BEGIN con_in.extend; con_in(con_in.last) := cur; END; ELSE BEGIN con_in.extend; con_in(1) := cur; END; END IF; IF (topstack() IS NOT NULL) AND (done=false) THEN BEGIN cur:=pop(); IF (cur=akt) THEN done:=true; END IF; dbms_output.put_line(cur); con_in.extend; con_in(con_in.last) := cur; END; END IF; OPEN c1(cur); FETCH c1 INTO li,re; CLOSE c1; cur:=re; END LOOP; END; --Postorder Traversierung PROCEDURE postorder (akt IN number) IS li number(12); re number(12); cur number(12); lt number(12); rt number(12); temp number(12); done boolean:=false; CURSOR c1(aktuell IN NUMBER) IS SELECT links, rechts FROM verbindung WHERE (aktuell = lfd); CURSOR c2(aktuell IN NUMBER) IS SELECT links, rechts FROM besucht_post WHERE (aktuell= lfd); BEGIN dbms_output.put_line('Postorder'); cur:=akt; IF (cur IS NOT NULL) THEN BEGIN OPEN c1(cur); FETCH c1 INTO li,re; CLOSE c1; INSERT INTO besucht_post VALUES (cur,li,re); push(cur); END; END IF; WHILE (cur IS NOT NULL) AND NOT is_empty AND NOT (done=true) LOOP LOOP OPEN c1(cur); FETCH c1 INTO li,re; CLOSE c1; OPEN c2(cur); FETCH c2 INTO lt,rt; IF (lt != li) OR (rt != re) OR (c2%NOTFOUND) THEN BEGIN push(cur); INSERT INTO besucht_post VALUES (cur,li,re); END; END IF; CLOSE c2; cur:=li; IF (li is NULL) AND (re IS NOT NULL) THEN cur:=re; END IF; EXIT WHEN (cur IS NULL); END LOOP; cur:=pop(); dbms_output.put_line(cur); IF (con_post.exists(con_post.last)) THEN BEGIN con_post.extend; con_post(con_post.last) := cur; END; ELSE BEGIN con_post.extend; con_post(1) := cur; END; END IF; IF (cur=akt) THEN done:=true; END IF; cur:=topstack(); OPEN c1(cur); FETCH c1 INTO li,re; CLOSE c1; cur:=re; END LOOP; END; --Levelorder Traversierung PROCEDURE levelorder(akt IN number) IS k1 mein_typ; li number(12); re number(12); cur number(12); CURSOR c1(aktuell IN number) IS SELECT links, rechts FROM verbindung WHERE (aktuell = lfd); BEGIN put(akt); con_level.extend; con_level(1) := akt; dbms_output.put_line('Levelorder'); WHILE (queue.exists(queue.first)) LOOP k1 := get(); dbms_output.put_line(k1.lfd); OPEN c1(k1.lfd); FETCH c1 INTO li, re; CLOSE c1; IF (li IS NOT NULL) THEN BEGIN con_level.extend; con_level(con_level.last) := li; put(li); END; END IF; IF (re IS NOT NULL) THEN BEGIN con_level.extend; con_level(con_level.last) := re; put(re); END; END IF; END LOOP; END; -- main BEGIN preorder(13); inorder(13); postorder(13); levelorder(13); FORALL i IN indices OF con_in INSERT INTO RESULT VALUES(con_pre(I),con_in(I),con_post(I),con_level(I)); END; / GRANT SELECT ON result TO PUBLIC; select * from result; Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.