Zur Haupt­na­vi­ga­ti­on sprin­gen [Alt]+[0] Zum Sei­ten­in­halt sprin­gen [Alt]+[1]

Dop­pel­stun­de 10: Tie­fen- und Brei­ten­su­che

In die­ser Dop­pel­stun­de wer­den die re­kur­si­ve Im­ple­men­ta­ti­on der Baum­tra­ver­sie­rung mit der ite­ra­ti­ven Im­ple­men­ta­ti­on ver­gli­chen. Die re­kur­si­ve Va­ri­an­te ist zwar ein­fa­cher zu for­mu­lie­ren und zu schrei­ben, stößt aber bei tie­fen Bäu­men an ihre Gren­zen. Dies kann man mit dem BlueJ-Pro­jekt 12_­tie­fer_baum (im Ord­ner Soft­ware) de­mons­trie­ren. Die Me­tho­de er­zeu­ge­Tie­fen­Baum(tiefe: int) baut einen Bi­när­baum auf, in dem die Kno­ten als rech­tes Kind einen Blatt­kno­ten haben und als lin­kes Kind eine be­lie­big lange Kette von Baum­kno­ten. Man er­zeugt einen sol­chen Baum mit einer Tiefe von min­des­tens 30.000 Ebe­nen und holt ihn auf die Ob­jekt­leis­te. Dann lässt man die Baumal­go­rith­men-Klas­se die An­zahl der Kno­ten im Baum be­stim­men. Das Er­geb­nis wird sein, dass das Pro­gramm mit einem „Stack Over­flow“-Feh­ler be­en­det wird. Der Grund ist, dass der Spei­cher­platz im Stack-Seg­ment stets re­la­tiv ge­ring ist, selbst wenn noch genug Spei­cher­platz im Daten-Seg­ment (wo be­lie­bi­ge Daten ab­ge­legt wer­den kön­nen, also vom Pro­gram­mie­rer an­ge­leg­te Va­ria­blen) vor­han­den ist.

Die Prä­sen­ta­ti­on 12_ba­e­u­me_3.odp zeigt, wie man die­ses Pro­blem um­geht, indem man den Stack „ma­nu­ell“ ver­wal­tet, dazu be­nö­tigt man ein ei­ge­nes Stack-Ob­jekt, das die noch zu ver­ar­bei­ten­den Baum­kno­ten ver­wal­tet („Todo-Liste“). Auf diese Weise kann auch eine Suche nach einem Kno­ten mit einer be­stimm­ten Ei­gen­schaft durch­ge­führt wer­den. Hier­bei han­delt es sich um eine Tie­fen­su­che, weil man den Baum zu­nächst „nach unten“ durch­sucht, bevor man wei­ter zur Seite wan­dert.

Als Ge­gen­stück dazu wird die Brei­ten­su­che de­mons­triert, indem man als Ver­ar­bei­tungs­stra­te­gie von „Last-in-first-out“ zu „First-in-first-out“ wech­selt. Dazu muss die Todo-Liste nur durch eine Queue er­setzt wer­den. Eine Brei­ten­su­che geht beim Su­chen „zu­nächst in die Brei­te“, weil zu­erst die ne­ben­ein­an­der­lie­gen­den Kno­ten einer Schicht ver­ar­bei­tet wer­den, bevor man wei­ter in die Tiefe geht. Die Un­ter­schei­dung zwi­schen Tie­fen- und Brei­ten­su­che ist bei Bäu­men we­ni­ger in­ter­es­sant als bei all­ge­mei­nen Gra­phen, da ein Pfad zu einem be­stimm­ten Kno­ten im Baum immer ein­deu­tig ist. Wenn es nur einen zu su­chen­den Kno­ten gibt, lie­fern Tie­fen- und Brei­ten­su­che also das­sel­be Er­geb­nis. In der Un­ter­richts­ein­heit zum Thema Gra­phal­go­rith­men wer­den Tie­fen- und Brei­ten­su­che noch­mals the­ma­ti­siert.

Ab­schlie­ßend kann man fest­stel­len, dass Stack und Queue sich struk­tu­rell sehr ähn­lich sind. Ab­ge­se­hen von der Be­nen­nung sind die Si­gna­tu­ren der bei­den ADTs iden­tisch. Man kann also eine ge­mein­sa­me Ober­klas­se „Con­tai­ner“ de­fi­nie­ren, die z.B. push(x: T) und en­queue(x: T) unter dem Namen „ein­fue­gen(x: T)“ zu­sam­men­fasst. Auf diese Weise kann man die bei­den Such­al­go­rith­men zu­sam­men­fas­sen und durch Wahl der kon­kre­ten Con­tai­ner­struk­tur ent­schei­den, wel­cher tat­säch­lich aus­ge­führt wer­den soll.

Zur prak­ti­schen Um­set­zung wird das Auf­ga­ben­blatt 12_­tie­fen_un­d_brei­ten­su­che.odt be­ar­bei­tet. Dort wer­den Tie­fen- und Brei­ten­su­che in der ite­ra­ti­ven Va­ri­an­te im­ple­men­tiert. Man be­nö­tigt also die be­reits ge­schrie­be­nen ADTs Stack und Queue aus den vor­an­ge­gan­ge­nen Un­ter­richts­stun­den.

 

Un­ter­richts­ver­lauf: Her­un­ter­la­den [odt][187 KB]

 

Wei­ter zu DS 11: Su­do­ku [nur LF, op­tio­nal]