Binärbaum Traversierung mit Endlichem Automat möglich?

Neue Frage »

Gulliveig Auf diesen Beitrag antworten »
Binärbaum Traversierung mit Endlichem Automat möglich?
Guten Abend,

nach nicht umweltgerechtem Befüllen des Papierkorbs mit Ansätzen in Kleinschrift auf A4 Papier trau ich mich mal die Frage ins Forum zu stellen:

Gegeben sei ein Binärbaum mit internen und externen Nodes. Interne Nodes tragen keine Daten, sondern nur Verweise zu keinem, einem oder zwei Nachfolgern ("Links" und "Rechts"). Externe Nodes tragen neben den Verweisen zusätzlich Daten.

Ziel ist es, einen beliebigen Teilbaum mittels eines finiten Automaten zu traversieren, und zwar pre-order, d.h. erst der Parent, dann das left child, dann das right child.

Beispiel:

Seit der Teilbaum gegeben mit:
code:
1:
2:
3:
4:
5:
6:
7:
(Root) Daten: A, Nur ein left-child vorhanden (L)
    (L) Intern, L + R vorhanden
        (L) Intern, L + R vorhanden
            (L) Daten: B, keine Nachfolger
            (R) Daten: C, nur left-child vorhanden
                (L) Daten: D, keine Nachfolger
        (R) Daten: E, keine Nachfolger
Dann werden bei pre-order traversal die externen Nodes (die mit Daten) in dieser Folge ausgegeben: A, B, C, D, E.

Nach JEDER Ausgabe hält der Automat in einem bestimmten Zustand. Bei Fortsetzung soll dann der nächste externe Node ausgegeben werden, mit Wegen gemäss dem aktuellen Zustand.

Weder eine rekursive noch eine iterative Lösung sind zulässig, da ich keinen variablen Speicher benutzen kann (Rekursiv: zur entweder zur Aufnahme der Funktion, iterativ: um mir die eingeschlagenen Richtungen zu merken).

Ich dachte daher daran, einen endlichen Automaten zu entwerfen. Die Anzahl der FEST zugeordneten Variablen (Stati) ist beinahe nebensächlich, aber es darf kein DYNAMISCH wachsender Stack ins Spiel kommen. Ich habe erste Ergebnisse mit Zuständen wie LE (left exists), RE (right exists), IN (internal node), usw., scheitere aber regelmässig daran, die richtige Verzweigung "weiter oben" zu finden und nicht alles nochmal zu durchlaufen.

Gibt es da irgendwo deutsch- oder englischsprachliche Literatur darüber? Bei Google finde ich nicht wirklich etwas brauchbares.

Danke für euren Input!
HAL 9000 Auf diesen Beitrag antworten »

Kommt m.E. drauf an, in welcher Form der Datenbaum "zugänglich" ist: Wenn es an jedem Knoten neben den Pointern auf die left/right-children auch einen auf den parent gibt, dann ist es m.E. schon mit einem endlichen Automaten möglich, das Ding zu traversieren.

Falls nicht, sehe ich auch keine Möglichkeit. Aber ich sehe das eher aus der praktischen Programmierersicht - theoretische Informatik ist nicht so mein Ding. Augenzwinkern
Gulliveig Auf diesen Beitrag antworten »

Ja, einen Parent haben die Nodes auch, sorry fürs Nichterwähnen.
HAL 9000 Auf diesen Beitrag antworten »

Müsste eigentlich einfach so gehen, im C-Code:

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
typedef struct _tTree tTree;

struct _tTree
{
    tTree   *left;
    tTree   *right;
    tTree   *parent;
    char     datum;
};

void traverse (tTree *root)
{
    tTree *node = root;
    tTree *lastchild = NULL;
    int up = 0;
    while (node != NULL)
    {
        if (up)
        {
            if ((lastchild == node->left) && (node->right != NULL))
            {
               node = node->right;
               up = 0;
            }
        }
        else
        {
            if (node->datum != 0)
            {
                print(node->datum);
            }
            if (node->left != NULL)
            {
                node = node->left;
            }
            else if (node->right != NULL)
            {
                node = node->right;
            }
            else
            {
                up = 1;
            }
        }
        if (up)
        {
           lastchild = node;
           node = node->parent;
        }
    }
}

Zu ergänzen wäre noch Funktion print, die das Datum (falls ungleich 0) ausgibt, der Rest ist soweit lauffähig.
Gulliveig Auf diesen Beitrag antworten »

Hallo HAL (ich liebe den Namen). Danke für deinen Post und die Zeit, nur: das ist die iterative Lösung. Die englischsprachige Wiki hat einen sehr kompakten Pseudocode dazu.

Ein finiter Automat kennt nicht wirklich Do...While Schleifen. Er weiss nur: ich bin bei Node B, und habe folgende Informationen (Zustände) aus vorangehenden Läufen: x, y, z...

Daraus (und nur daraus) muss er das nächste Ereignis hervorbringen (und zwar genau nur eines, nämlich C). Dann hört der Automat auf zu arbeiten, nix mit Schleifen. Beim nächsten Aufruf weiss er: ich bin bei C, und habe folgende Zustände: x2, y2, z2, die sich aus dem vorangehenden Aufruf ergeben haben.
HAL 9000 Auf diesen Beitrag antworten »

Zitat:
Original von Gulliveig
nur: das ist die iterative Lösung.

Ich dachte, es kommt dir drauf an, dass nur endlich viele (d.h. von der Baumgröße unabhängig viele) Daten (Variablen+Stack) benötigt werden - und das erfüllt der Algorithmus. Na egal, viel Spaß noch bei der Suche - ist mir ein Rätsel, wie du das ohne Schleifen bewältigen willst. unglücklich

Zitat:
Original von Gulliveig
Daraus (und nur daraus) muss er das nächste Ereignis hervorbringen (und zwar genau nur eines, nämlich C). Dann hört der Automat auf zu arbeiten, nix mit Schleifen. Beim nächsten Aufruf weiss er: ich bin bei C, und habe folgende Zustände: x2, y2, z2, die sich aus dem vorangehenden Aufruf ergeben haben.

Das ist m.E. Krümelkackerei: Die dauernde Aufruf-Wiederholung ist doch sowas wie eine Schleife. smile
 
 
Gulliveig Auf diesen Beitrag antworten »

Ja, wie gesagt, danke für die Zeit. Aber nein, keine Schleife, sorry für die Krümelkackerei, das ist nicht... Ach egal, wie üblich, 10000+ posts gewinnt über 1+ post: publish or perish.

Endliche Automaten sind anders gewickelt als iterative oder rekursive Prozeduren, aber das schrieb ich ja im Eingangspost. Sie funktionieren wie in der deutschen Wiki ersichtlich unter: Endlicher Automat, oder besser in der englischen Wiki, unter Finite-state machine.

PS: Würde mich aber dennoch über Antworten freuen, die finite Automaten zum Thema haben, obwohl ich nach 72+ Arbeitsstunden mittlerweile vermute, dass es keine theoretische Lösung geben KANN, weil es IMMER einen variablen Stack benötigt bei indefinitiv tiefen Binärbäumen (?) - und deshalb wahrscheinlich auch die mangelnde Trefferquoute bei Google. Einen Beweis zu erbringen dürfte länger dauern (es sei denn es gäbe bereits einen?).

Viele Grüsse (, und sorry, HAL, keine Probleme, ich hab mich wahrscheinlich einfach nicht genau genug ausgedrückt.)
HAL 9000 Auf diesen Beitrag antworten »

Zitat:
Original von Gulliveig
mittlerweile vermute, dass es keine theoretische Lösung geben KANN, weil es IMMER einen variablen Stack benötigt bei indefinitiv tiefen Binärbäumen (?)

Nun ja, meine Lösung oben funktioniert für indefinitiv tiefen Binärbäume nur deswegen nicht, weil irgendwann mal Pointer fester Speichergröße eine riesige Knotenzahl nicht mehr addressieren kann. Aber dieses Problem hast du bei jedem solchen Algorithmus - ja, bereits die Speicherung der Baumes ist davon betroffen, dass man bei immer größer werdenen Bäumen diese "left,right,parent"-Pointer in ihrer Speichergröße reorganisieren muss. unglücklich


Vielleicht versuchst du es mal im Informatikerboard, da besteht vielleicht mehr Verständnis für dein Anliegen. Und so einen Müll wie den hier

Zitat:
Original von Gulliveig
Ach egal, wie üblich, 10000+ posts gewinnt über 1+ post: publish or perish.

unterlässt du da besser: Die wenigen beleidigen, die sich überhaupt mit deinem Anliegen auseinandersetzen, ist nicht gerade feiner Stil. Finger2
Neue Frage »
Antworten »



Verwandte Themen

Die Beliebtesten »
Die Größten »
Die Neuesten »