# Implementing leaf and non-leaf node by using parametric type

**URL:** <https://discourse.julialang.org/t/implementing-leaf-and-non-leaf-node-by-using-parametric-type/77686>\
**Category:** General Usage\
**Tags:** question\
**Created:** [March 10, 2022, 1:45pm UTC](https://discourse.julialang.org/t/implementing-leaf-and-non-leaf-node-by-using-parametric-type/77686 "2022-03-10T13:45:18Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![ykkan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ykkan/32/14541_2.png) [@ykkan](https://discourse.julialang.org/u/ykkan)\
**Post date:** [March 10, 2022, 1:45pm UTC](https://discourse.julialang.org/t/implementing-leaf-and-non-leaf-node-by-using-parametric-type/77686/1 "2022-03-10T13:45:18Z")

</div>

Hello everyone,  
I would like to implement a binary tree by using the parametric type instead of inheritance.  
The structure is something like

```julia
# leaf node
struct Node{T}
  vale::T
  first_weights::Nothing
  second_weights::Nothing
  lchild::Nothing
  rchild::Nothing
end

#non-leaf node
struct Node{T}
  vale::T
  first_weights::Vector{T}
  second_weights::Vector{T}
  lchild::Node{T}
  rchild::Node{T}
end

```

For a leaf node, the types of `first_weights`, `second_weights`, `lchild` and `rchild` are `Nothing`.

The idea I have so far is

```julia
struct Node{T,W<:Union{Vector{T},Nothing},ND<:Union{Node,Nothing}}
  val::T
  first_weights::W
  second_weights::W
  lchild::ND
  rchild::ND
end

```

However, this design allows the possibility, for example

```julia
# an unreasonable Node
struct Node{T}
  vale::T
  first_weights::Vector{T}
  second_weights::Vector{T}
  lchild::Nothing
  rchild::Nothing
end

```

How can I avoid this problem? Is there any better ways to design this structure? Thanks.

* * *

Solution provided by @Henrique_Becker: defining a internal structure `Branch`.

```julia
struct Node{T}
  value::T
  branch::Union{Nothing,Branch{T}}
end

struct Branch{T}
  first_weights::Vector{T}
  second_weights::Vector{T}
  lchild::Node{T}
  rchild::Node{T}
end

```

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [March 10, 2022, 2:26pm UTC](https://discourse.julialang.org/t/implementing-leaf-and-non-leaf-node-by-using-parametric-type/77686/2 "2022-03-10T14:26:15Z")

</div>

Instead of the four last fields you could use two fields (one for each side) that are either `nothing` or a composite internal struct (lets call it `Branch{T}`) that has the two associated fields (`child` and `weights`). Note the `child` and `weights` do not need to support `Nothing` values as the `Branch{T}` will only exist if it exists.

---

<div class="post-metadata">

**Author:** ![ykkan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ykkan/32/14541_2.png) [@ykkan](https://discourse.julialang.org/u/ykkan)\
**Post date:** [March 11, 2022, 9:38am UTC](https://discourse.julialang.org/t/implementing-leaf-and-non-leaf-node-by-using-parametric-type/77686/3 "2022-03-11T09:38:30Z")

</div>

Thanks for your reply. I just updated your solution to the post.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [March 11, 2022, 1:15pm UTC](https://discourse.julialang.org/t/implementing-leaf-and-non-leaf-node-by-using-parametric-type/77686/4 "2022-03-11T13:15:20Z")

</div>

Is the tree complete? (This is, it always has the two branches or none?) What I proposed was slightly different:

```julia
struct Branch{T, W}
  weights::Vector{W}
  child::Node{T, W}
end

struct Node{T, W}
  value::T
  left::Union{Nothing,Branch{W}}
  right::Union{Nothing,Branch{W}}
end

```
