2014-07-13 11 views
7

Für zwei Mehrweg-Bäume, T1 und T2 definiertWie verschiebe ich einen Teilbaum zwischen Bäumen in Haskell?

type Forest a = [Tree a] 
data Tree a = Node { 
     rootLabel :: a,  
     subForest :: Forest a 
    } 

Wie kann ich eine Funktion schreiben, die eine Teilstruktur von t1 entfernen werden und es zu einem bestimmten Knoten in t2 einfügen?

Ich stelle mir die Signatur so etwas wie

moveSubTree :: ((Tree x a) x (Tree x a)) -> (Tree x Tree) 

aussehen würde also ein Baum und übergeordneten Knoten, die einen Teilbaum nimmt entfernt werden, und einen zweiten Baum, und der Knoten, der den Punkt, an dem bestimmt den ursprünglichen einzufügen Teilbaum.

Getrennte Funktionen zum Entfernen und Hinzufügen des Teilbaums können bei Bedarf zusammengestellt werden.

+5

Was ist 'x'? Außerdem hat Haskell keine Hinweise. Ein Tree-Wert ist nur ein Tree, kein Unterbaum von irgendetwas. Sie müssen eine Möglichkeit bereitstellen, um einen Teilbaum aus einem Baum zu erhalten, wie den Pfad (eine Liste von Indizes). –

+1

Sie müssen spezifischer sein als "... fügen Sie es in einer bestimmten Tiefe in t2 ein" - Es kann mehrere Punkte im Baum in jeder gegebenen Tiefe geben, zu welchem ​​Punkt möchten Sie ihn verschieben? –

+0

Das macht Sinn - ich hätte setzen sollen "fügen Sie es an einem bestimmten Knoten in t2". Ich werde die Frage aktualisieren, um dies zu berücksichtigen. –

Antwort

9

Sie können Änderungen vornehmen und "an einem Pfad" in einem Baum lesen.

data Dir = L | R 
type Path = [Dir] 
data Tree a = Leaf | Node a (Tree a) (Tree a) 

read :: Path -> Tree a -> Maybe (Tree a) 
read []  t = t 
read (s:ss) t = case t of 
    Leaf  -> Nothing 
    Node a l r -> case s of 
    L -> read ss l 
    R -> read ss r 

edit :: Path -> (Tree a -> Tree a) -> Tree a -> Maybe (Tree a) 
edit []  f t = Just (f t) 
edit (s:ss) f t = case t of 
    Leaf  -> Nothing 
    Node a l r -> case s of 
    L -> do 
     l' <- edit ss f l 
     return (Node a l' r) 
    R -> do 
     r' <- edit ss f r 
     return (Node a l r') 

Und dann mit diesem Tool können Sie „Kopieren und Einfügen“ Teilbäume von einem Pfad zu einem anderen

cnp :: Path -> Path -> Tree a -> Maybe (Tree a) 
cnp readPath writePath t = do 
    subtree <- read readPath t 
    edit writePath (const subtree) t 

Interessanterweise „Baum, der an Pfad“ bildet eine Lens, die die gemeinsame Struktur zwischen diesen beiden subsumiert Operationen.

+2

Ein kleiner Nitpick, TS wollte einen Mehrwege-Baum, nicht binär. –

+2

Wahr. Diese Idee verallgemeinert sich auf Multi-Way-Bäume, indem 'type Path = [Int]' verwendet wird und festgestellt wird, dass Pfade "übersehen" können, indem sie zu lang sind und auf einen nicht existierenden Teilbaum verweisen. –

Verwandte Themen