| 

.NET C# Java Javascript Exception

3
Aus einer unsortierten Liste mit Parent-Child Beziehungen möchte ich eine Baumstruktur erzeugen.
Nehmen wir an ich habe folgende Liste:
Parent: | Child:
100 | 101
101 | 201
101 | 301
101 | 401
401 | 421
100 | 205
100 | 305
305 | 421
...
Ich möchte nun einen Algorithmus in C# implementieren mit dessen Hilfe ich bei Angabe einer Parent-Nr. einen Baum erzeuge, der alle darunterliegenden Parent-Child-Beziehungen enthält.
Also wenn ich z.B. Parent-ID: 101 als Startwert (Root) angebe, so soll folgende Baumstruktur erzeugt werden:
101
...|_ 201
...|_ 301
...|_ 401
........|_421

Je nach dem welche Parent-ID ich angebe, kann ich unterschieldiche Baumstrukturen erhalten.
Wie muss dieser Algorithmus aussehn?
13.09.2011
Gast
31 2
3 Antworten
2
Du brauchst eine Datenstruktur, die einen Knoten repräsentiert. Ein Knoten hat eine ID und eine Liste von Kindknoten. Außerdem brauchst Du ein Verzeichnis, in dem du zu einer ID den zugehörigen Knoten nachschlagen kannst.

Dann läufst Du alle ID-Paare ab. Für jede ID holst Du Dir den Knoten aus dem Verzeichnis. Wenn es ihn noch nicht gibt, erzeugst Du ihn und legst ihn im Verzeichnis ab. Dann fügst Du den Kindknoten der Kinder-Liste des Elternknoten hinzu. Dann weiter mit dem nächsten ID-Paar.

Am Ende schlägst Du im Verzeichnis den Knoten mit der gegebenen ID nach.

Soweit die einfache Variante, und jetzt zu den Knackpunkten. Kompliziert wird es, wenn

  • Du den Komplett-Baum aller Knoten nicht erzeugen kannst/willst (z.B. weil es zuviele Knoten sind)
  • Du überprüfen mußt, ob Deine Eingangsdaten überhaupt einen Baum ergeben, z.B. weil es einen Kreis darin gibt:
    1 2
    2 3
    3 1
    oder Knoten mit mehreren Eltern vorkommen:
    1 2
    1 3
    2 4
    3 4

Wenn Du solche Anforderungen hast, dann ergänze bitte noch Deine Frage um entsprechende Hinweise.
13.09.2011
Matthias Hlawatsch 8,4k 2 8
Es soll immer der komplette Baum erzeugt werden.
Kreise können ebenso vorkommen wie Mehrfachreferenzen, also Knoten mit mehreren Eltern.
– Gast 13.09.2011
Heißt sowas dann nicht Graph?
ffordermaier 13.09.2011
So ist es. Man brauch dann eine Kreiserkennung als Abbruchkriterium. Das kann man dadurch erreichen indem man beim Hinzufügen eines Knotens prüft, ob derselbe Knoten bereits in der Kette zwischen Start-und aktuellem Knoten vorkommt.
puls200 13.09.2011
Im Falle eines Kreises soll ein Knoten einfach mehrfach im Baum vorkommen, allerdings nur einmal innerhalb des Baumes mit den darunterliegenden Kindern. Dies gilt auch für Mehrfachreferenzen.
– Gast 13.09.2011
Ein gerichteter Graph, um genau zu sein (http://de.wikipedia.org/wiki/Graph_%28Graphentheorie%29#Gerichteter_Graph). Jedenfalls würde ich die Aufgabenstellung so interpretieren, denn sonst ergibt es m.E. keinen Sinn, von Parent und Child zu sprechen. Was mir jetzt aber nicht klar ist: heißt "können vorkommen", dass die zu erzeugende Struktur kein Baum sein muss, sondern allg. ein ger. Graph sein darf, oder heißt es, daß die Erzeugung der Baumstruktur mit einem Fehler abbrechen soll, wenn sich herausstellt, dass kein Baum vorliegt?
Matthias Hlawatsch 13.09.2011
Hier noch ein Link zur Zyklensuche:
http://www-i1.informatik.rwth-aachen.de/~algorithmus/algo35.php
Matthias Hlawatsch 13.09.2011
@Neues Mitglied: "einfach mehrfach im Baum vorkommen" - das verstehe ich nicht. Erstens ist es mit Kreis kein Baum mehr, zweitens ist ein Knoten in einem Graph immer genau einmal enthalten, sonst ergibt die ganze Begriffsbildung keinen Sinn mehr.
Matthias Hlawatsch 13.09.2011
Kreis:
1
|_2
..|_3
....|_1
Da die 1 schon im Baum (Graph, Organigramm oder wie man es auch nennen mag) schon enthalten ist sollen die Kinder nicht mehr angezeigt werden.

Ein Baum mit mehreren Eltern sollte dann so aussehn:
1
|_2
..|_4
|_3
..|_4

Wenn 4 auch auch noch Kinder hat, dann sollen diese Kinder nur beim erstmaligen Vorkommen des Knotens 4 angezeigt werden.

– Gast 13.09.2011
OK, so langsam verstehe ich. Dann trenne die interne Repräsentation der Datenstruktur von der Darstellung. Der Algorithmus in meiner Antwort bleibt, wie er ist, auch die Datenstruktur (die dann einen ger. Graph repräsentiert). Für die Anzeige fängst Du beim Wurzelknoten an und merkst Dir, welche Knoten Du schon anzeigt hast. Kommt ein Knoten ein zweites Mal vor, wird nur noch er selbst angezeigt, aber nicht mehr seine Kinder.
Matthias Hlawatsch 13.09.2011
@Neues Mitglied:
Zitat: "Je nach dem welche Parent-ID ich angebe, ..."
Das widerspricht aber der Aussage, dass der Baum mehrere Eltern haben kann. Entweder man gibt eine ParentId vor, dann hat man nur eine oder man kann mehrere haben. In deinem Kommentar hat dein Graph die Eltern 1 und 3.
Kannst du das nochmals genauer beschreiben?
PS: Die Aufgabe ist interessant.
Jürgen Luhr 13.09.2011
2
Ich habe hier kurz etwas skizziert, bitte nur als Pseudocode verstehen, ungetestet:

using System;

public class Node
{
public Guid Id;
public Guid ParentId;
public Node Parent;
public List<Node> Children = new List<Node>();

public static Node TreeFromNode(Guid rootId, List<Node> unsortedList)
{
foreach (Node node in unsortedList)
{
if (node.Id == rootId)
{
AddSubNodes(node, unsortedList);
}
}
}

public static void AddSubNodes(Node currentNode, List<Node> allNodes)
{
foreach (Node node in allNodes)
{
if (node.ParentId == currentNode.Id) // child found
{
currentNode.Children.Add(node);
node.Parent = currentNode;
}
if(!IsNodeInPath(currentNode, node.Id))
AddSubNodes(node, allNodes);
}
}

public static bool IsNodeInPath(Node node, Guid id)
{
if (node.Id == id) return true;
if (node.Parent != null)
return IsNodeInPath(node.Parent, id);
return false;
}
}


Mit der Methode TreeFromNode wird der Graph ab rootId aufgebaut. AddSubNodes() und der Kreis-Test IsInNodePath() arbeiten jeweils rekursiv.
Das kann dir evtl. als Anregung helfen. Ich bin sicher, die Profis hier im Forum liefern in Kürze noch eine elegantere (und vermutlich fehlerbereinigte) Variante :-)

Gruß
Daniel
13.09.2011
puls200 3,3k 6
Hm, hier fällt mir sofort auf, dass Du von genau einem Parent pro Node ausgehst. Der OP (gibt es eine deutsche Abkürzung für Original Poster?) hat aber inzwischen klargestellt, dass ein Knoten mehrere Eltern haben kann.
Matthias Hlawatsch 13.09.2011
Ja, im jeweiligen Zweig. Es heisst ja nicht dass ein Knoten nicht in mehreren Zweigen vorkommen kann (und damit diese Bed. erfüllt ist). Der OP (klingt doch gut! :-) ) möchte den Graphen doch ab einem definierten Punkt ausgeben.
puls200 13.09.2011
@Matthias: Deutsch für "OP" ist hier "Neues Mitglied" ;o)
Jürgen Luhr 13.09.2011
0
Hallo,

ich würde zuerst alle items in einem Dictionary (ID, Item) laden.

Anschließend kannst du über die Items iterieren, über die ParentID das entsprechende parentItem aus dem Dictionary holen und dem parentItem das aktuelle item als child zuweisen.

Alle items ohne parentID bilden die Wurzelelemente.


Viele Grüße,
Tachyon
13.09.2011
Tachyon 690 6

Stelle deine Algorithmus-Frage jetzt!
Sevitec Gruppe
InnoGames GmbH
infounit Software GmbH
myfactory International GmbH