Get the parent of a node in Data.Tree (haskell) - haskell

I need a tree implementation where I can access the parent node of any node in the tree. Looking at Data.Tree I see the tree definition:
data Tree a = Node {
rootLabel :: a, -- ^ label value
subForest :: Forest a -- ^ zero or more child trees
}
So if I have a tree node Tree a I can access its label and its children. But it is also possible to access its parent node? Do have to choose a different implementation for my needs? Which package would you recommend?

If I'm not mistaken, what you're asking for is basically what gets implemented in LYAH's section on Zippers.
I won't attempt to explain it better than Miran did, but the basic idea is to keep track of which tree you're coming from, as well as which branch you're moving down, while you traverse the tree. You're not keeping track of the node's parent directly in the data structure, but all of the information will be available when you traverse the tree.

Data.Tree deliberately does not have nodes reference their own parents. This way, changes to parent nodes (or nodes in other branches) do not need to re-create the entire tree, and nodes in memory may be shared with multiple trees. The term for structures like this is "persistent".
You may implement a node which knows its own parent; the resulting structure will not be persistent. The clear alternative is to always know where the root node of your tree is; that's good practice in any language.
One library that does allow Data.Tree to know its parents is rosezipper, documentation can be found here.

Try this:
data Tree a = Leaf | Node a (Tree a) (Tree a) (Tree a) deriving (Eq, Show)
You can save the parent tree into the third(or any other) tree.
Example:
singleton::(Ord a)=>a->Tree a
singleton x = Node x Leaf Leaf Leaf
insert::(Ord a)=>a->Tree a->Tree a
insert x Leaf = singleton x
insert x t#(Node a l r p) = insertIt x t p
where insertIt x Leaf (Node a l r p) = Node x Leaf Leaf (Node a Leaf Leaf Leaf)--1*
insertIt x t#(Node a l r p) parent
| x == a = t
| x < a = Node a (insertIt x l t) r p
| x > a = Node a l (insertIt x l t) p
1* in this row you can save the whole parent:
where insertIt x Leaf parent = Node x Leaf Leaf parent

Related

Can you implement Binary Search Tree in Haskell with O(log n) insertion?

If I understand correctly, modifying (insertion or deletion) a Binary Search Tree in Haskell requires copying the whole tree, so practically making it being O(n). Is there a way to implement it in O(log n) or maybe compiler would optimize O(n) insertion down to O(log n) "under the hood"?
If I understand correctly, modifying (insertion or deletion) a Binary Search Tree in Haskell requires copying the whole tree, so practically making it being O(n).
You do not need to copy the entire tree. Indeed, let us work with a simple unbalanced binary search tree, like:
data Tree a = Node (Tree a) a (Tree a) | Empty deriving (Eq, Show)
then we can insert a value with:
insertIn :: Ord a => a -> Tree a -> Tree a
insertIn x = go
where go Empty = Node Empty x Empty
go n#(Node l v r)
| x < v = Node (go l) v r
| x > v = Node l v (go r)
| otherwise = n
Here we reuse r in case we construct a Node (go l) v r, and we reuse l in case we construct a Node l v (go r). For each node we visit, we create a new node where one of the two subtrees is used in the new node. This means that the new tree will point to the same subtree objects as the original tree.
In this example, the amount of new nodes thus scales with O(d) with d the depth of the tree. If the tree is fairly balanced, than it will insert in O(log n).
Of course you can improve the algorithm and define an AVL tree or red-black tree by storing more information in the node regarding balancing, in that case you thus can guarantee O(log n) insertion time.
The fact that all data is immutable here helps to reuse parts of the tree: we know that l and r can not change, so the two trees will share a large amount of nodes and thus reduce the amount of memory necessary if you want to use both the original and the new tree.
If there is no reference to the old tree necessary, the garbage collector will eventually collect the "old" nodes that have been replaced by the new tree.

Labeling a tree depth-first in-order in haskell

I basicly have the same question as asked here: Haskell label a binary tree through depht-first in-order traversel but the answer there was never actually given and I can't comment there due to lack of reputation.
Right now i have a function label:
label :: MonadState m Int => Tree a -> m (Tree (Int, a))
label Leaf = return Leaf
label (Branch leftTree a rightTree) = do n <- get
modify (+1)
l' <- label leftTree
r' <- label rightTree
return (Branch l' (n,a) r')
where Tree a = Leaf | Branch (Tree a) a (Tree a).
Now this labels the tree breadth-first. Now I want to label the leftTree first, then the Branch itself and then the rightTree, but I don't see how to achieve this and the other thread doesn't help me further.
I just answered the older question here. Sorry for mistakenly attributing to to you. The point is that when you wrote your type, you also told Haskell how to traverse your data structure in a way that ensures the get happens in the middle.
The program that you locally wrote incorrectly yourself is a program you already wrote correctly just by defining your type, had you only known.

confused about the type of the Instance of a binary tree data type of Int Nodes in Haskell

I made a binary tree data type in Haskell, according to this code:
data Tree a = EmptyTree
| Node a
(Tree a) (Tree a) deriving (Show,Eq)
and I also created a function to insert elements in the tree:
treeinsert :: (Ord a) => a -> Tree a -> Tree a
treeinsert x EmptyTree = leaf x
treeinsert x (Node a left right)
| x == a = Node x left right
| x < a = Node a (treeinsert x left) right
| x > a = Node a left (treeinsert x right)
Now, for testing I am using a list of Int elements, like this:
ghci> let nums = [8,6,4,1,7,3,5]
ghci> let numsTree = foldr treeInsert EmptyTree nums
ghci> numsTree
Node 5 (Node 3 (Node 1 EmptyTree EmptyTree) (Node 4 EmptyTree EmptyTree)) (Node 7 (Node 6 EmptyTree EmptyTree) (Node 8 EmptyTree EmptyTree))
My question is when I check the type of numsTree:
:type numsTree
numsTree :: Tree Integer
Why doesn't it just have the type of "Tree"?
I am a little confused.
(sorry for my language)
You defined the type Tree as a parametrised type. The a after Tree in the data type's definition is this parameter. This means that there is not just one Tree type, but many different ones. For example, you can have a type Tree Integer containing integers, a type Tree Bool containing booleans and a type Tree (String -> String) containing functions from string to string.
Note that it's a good thing that you can distinguish these different types. It means that when you get a value out of such a tree, you know which type of value you're going to get. If there was just one Tree type, then you wouldn't be able to find out.
Why doesn't it just have the type of "Tree"?
Because you explicitly pass the list of numbers to it which restricts the type.
If you define nTree = foldr treeInsert(in ghci prepend a let) you get the expected more general type. By the way, you may want to add Leaf a as another data constructor.

Help In Declaring Variable Number Of Arguments

High Guys,
I have to define a polymorphic datatype for a tree that can have multiple nodes. Each node can have any number of children and a vlaue. This type will always have at least one node. I am new in Haskell so am asking how can i declare the node to have variable number of arguments.
This is what i have now. This is a tree that can have a Node or a node with value (a) and two tree children. Instead of two tree children, i want them to be any number of tree children. (Analoog as java variable number of arguments "arg...")
data Tree a = Node a | Node a (Tree a) (Tree a) deriving (Show)
Thanks for your help
EDIT
A little question::: How can i declare this node with variable arguments in a functions
parameter(header/signature). I have to implement a function called
"contains" which will check if a Node contains a specific element.
contains :: Tree a -> b -> Bool
contains (Node val [(tree)]) = ......
Is the second line correct ?
it would be:
data Tree a = Node a | Node a [(Tree a)] deriving (Show)
but in addition there is a second problem that this should be
data Tree a = Leaf a | Branch a [(Tree a)] deriving (Show)
or such as the parts of a union must have different names as otherwise you couldn't use pattern matching
Leaf and Branch are data constructors so:
Branch 1 [Leaf 3, Branch 6 [Leaf 5]]
is an example of a Tree
contains :: Tree a -> a -> Boolean
contains (Leaf a) b = a == b
contains (Branch a c) b = a == b || any (map (\t -> contains t b) c)
or such

Converting rose trees to different binary tree types

I am completely lost on how to do some tree conversions in Haskell. I need to go from a rose tree defined as:
data Rose a = Node a [Rose a] deriving (Eq, Show, Ord)
to a binary tree which is defined as:
data Btree a = Empty | Fork a (Btree a) (Btree a) deriving (Eq, Show, Ord)
In my class I was given a function that is similar, but using a different definition of the binary tree. For that function the rose tree is defined the same and the binary tree is defined as:
Btree a = Leaf a | Fork (Btree a) (Btree a)
with the function from rose tree to binary tree defined as:
toB :: Rose a -> Btree a
toB (Node x xts) = foldl Fork (Leaf x) (map toB xts)
toB (Node x []) = foldl Fork (Leaf x) []
I have the answer but I don't know how to convert it so that it works with the new definition of Btree.
When I did something like this, I considered the "left" subtree to be the first child, and the "right" subtree to be the siblings of the node. This means that you convert the tree like so:
h h
/|\ /
/ | \ /
b d e ==> b->d->e
/ \ / \ / /
a c f g a->c f->g
h is still the root, but in the second diagram / is the left subtree and -> is the right. Leaves have no left subtree, but might have siblings (right subtrees). The root has no right subtree, but might have children (left subtree). Internal nodes have both.
Does that help?
Try to write a function converting from the first to the second definition of the binary tree. Then convB . toB is your new function! Now, systematically create a new function that acts directly as a fusion of the two, by inlining one into the other, and you'll get a straightforward and elegant solution.

Resources