Binärer Baum rekursiv definiert

Vorbemerkung

Vor diesem Abschnitt sollten Sie zuerst die Einführung in die Rekursion lesen.

Ergebnis der swf-Datei

Die Funktion wird rekursiv definiert. Im Anweisungblock wird die Funktion zweimal rekursiv aufgerufen.

Das Prinzip der Rekusion

Der Programmcode ohne Erklärungen

Codeabschnitte, die sich nicht vom vorigen Arbeitsschritt unterscheiden, werden grau geschrieben.

// BÜHNENRECHTECK MIT FARBE FÜLLEN UND KONTURIEREN
fillStage(1, 0xFF0000, 0xCCCCFF);
//
// ZEICHNEN EINES REKURSIVEN BINÄREN BAUMES
//
var point = new Array();
point.x = Stage.width/2;
point.y = 0;
binaryTree(point, 200, 300, 1, 0xFF0000);
/*
DEKLARATION DER FUNKTIONEN binaryTree(), baseCurve() UND fillStage()
*/
function binaryTree(pt:Array, a:Number, b:Number, lineWidth:Number, lineColor:Number):Void {
if (a>=3 && b>=2) {
this.lineStyle(lineWidth, lineColor);
this.moveTo(pt.x, pt.y);
var pts:Array = baseCurve(pt, a, b);
binaryTree(pts[0], a/2, b/2, lineWidth, lineColor);
binaryTree(pts[1], a/2, b/2, lineWidth, lineColor);
}
}
function baseCurve(pt:Array, a:Number, b:Number):Array {
this.lineTo(pt.x, pt.y+a/4);
this.moveTo(pt.x-b/2, pt.y+a);
this.curveTo(pt.x-b/2, pt.y+a/4, pt.x, pt.y+a/4);
this.curveTo(pt.x+b/2, pt.y+a/4, pt.x+b/2, pt.y+a);
var pt1 = new Array();
var pt2 = new Array();
pt1.x = pt.x-b/2;
pt1.y = pt.y+a;
pt2.x = pt1.x+b;
pt2.y = pt1.y;
return [pt1, pt2];
}
function fillStage(lineWidth:Number, lineColor:Number, fillColor:Number):Void {
this.lineStyle(lineWidth, lineColor);
this.beginFill(fillColor);
this.moveTo(0, 0);
this.lineTo(Stage.width-1, 0);
this.lineTo(Stage.width-1, Stage.height-1);
this.lineTo(0, Stage.height-1);
this.lineTo(0, 0);
this.endFill();
}


Der Programmcode mit Erklärungen

Ausgangspunkt festlegen und rekursive Funktion binaryTree aufrufen

var point = new Array();
point.x = Stage.width/2;
point.y = 0;
binaryTree(point, 200, 300, 1, 0xFF0000);

Die Mitte der oberen Bühnenkante wird als Ausgangspunkt festgelegt.
Der Baum wird ausgehend von diesem Punkt mit der Höhe 200 und Breite 300 für die Ausgangsbasiskurve in rot und mit 1 Pixel Strichstärke gezeichnet.

Definition der Basiskurve


Ausgangspunkt ist der Punkt pt (implementiert als Array) mit den Koordinaten pt.x und pt.y (in der Grafik x | y).
Die Basisbaum mit einem Stamm und zwei Ästen wird entsprechend der Grafik gezeichnet, wobei einmal der Stift mit moveTo von (x | y+a/4) nach (x-b/2 | y+a) springt.
Abschließend werden die Endpunkte der beiden Äste als Array abgespeichert und in einem weiteren Array zuückgegeben.
D.h. zuückgegeben wird ein Array mit zwei Elementen, die wiederum Arrays sind (geschachteltes Array).

function baseCurve(pt:Array, a:Number, b:Number):Array {
this.lineTo(pt.x, pt.y+a/4);
this.moveTo(pt.x-b/2, pt.y+a);
this.curveTo(pt.x-b/2, pt.y+a/4, pt.x, pt.y+a/4);
this.curveTo(pt.x+b/2, pt.y+a/4, pt.x+b/2, pt.y+a);
var pt1 = new Array();
var pt2 = new Array();
pt1.x = pt.x-b/2;
pt1.y = pt.y+a;
pt2.x = pt1.x+b;
pt2.y = pt1.y;
return [pt1, pt2];
}

Definition der Funktion für den binären Baum

Eingabeparamter von der Funktion binaryTree sind der Ausgangspunkt pt, Höhe a und Breite b des Basisbaums, sowie die Anfangsstrichstärke lineWidth und -farbe lineColor.

Nur wenn Höhe a und Breite b des Basisbaums über den fixen Grenzwerten 3 und 2 liegen, wird ein neuer Teilbaum gezeichnet.

Zuerst wird der Linienstil festgelegt und der Zeichenstift beim Ausgangspunkt positioniert.
Anschließend wird durch den Aufruf der Funktion baseCurve der Basisbaum mit Höhe a und Breite b gezeichnet. Die Funktion gibt ein Array mit den zwei Endpunkten zurück, das unter dem Array pts abgespeichert wird.
D.h mit var pts:Array = baseCurve(pt, a, b); wird eine Variable vom Typ Array definiert, der gleich das Ergebnis des Funktionsaufrufs baseCurve(pt, a, b); als Wert zugewiesen wird.

Zuletzt wird zweimal rekursiv die Funktion binaryTree mit neuen Eingabewerten aufgerufen:

  • Neue Ausgangspunkte sind die zwei Endpunkte des vorhergehenden Basisbaums pts[0] und pts[1] .
  • Die Breite a und Höhe b der nächsten Basisbäume wird halbiert. Dadurch wird das Problem auf dasselbe kleinere Problem reduziert.
    Breite a und Höhe b werden solange halbiert bis einer der beiden Grenzwerte unterschritten ist.
  • Linienstärke und -farbe bleiben unverändert.

function binaryTree(pt:Array, a:Number, b:Number, lineWidth:Number, lineColor:Number):Void {
if (a>=3 && b>=2) {
this.lineStyle(lineWidth, lineColor);
this.moveTo(pt.x, pt.y);
var pts:Array = baseCurve(pt, a, b);
binaryTree(pts[0], a/2, b/2, lineWidth, lineColor);
binaryTree(pts[1], a/2, b/2, lineWidth, lineColor);
}
}

Variation

Auch in diesem Beispiel kann man durch gezieltes Variieren von Strichstärke und -farbe zusätzliche Effekte erzielen:

Bei den rekursiven Aufrufen wird die Linienstärke um 10% reduziert (*0.9) und die Farbe schrittweise heller und in Richtung Gelb (+0x0F1F00) verschoben.

binaryTree(pts[0], a/2, b/2, lineWidth*0.9, lineColor+0x0F1F00);
binaryTree(pts[1], a/2, b/2, lineWidth*0.9, lineColor+0x0F1F00);

Funktionsaufruf mit Linienstärke 8 und einem Braunton (= dunkles Rot):

binaryTree(point, 200, 300, 8, 0x990000);