You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: source/lectures/data/trees.md
+75-10Lines changed: 75 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,33 +13,98 @@ As an abstract data type, it generally uses the following definitions:
13
13
- A binary tree is made of *nodes*, each of which contain *one value*, can have up to 2 *children*.
14
14
- A (rooted) binary tree has exactly one node with 0 parent (that is not the child of any other node), called *the root*. Except for the root, all the nodes have exactly one parent.
15
15
- A *leaf* is a node *without children*.
16
-
- The *depth of a node* is the distance (i.e., the number of times we must go to its parent) from it to the root.
16
+
- The *depth of a node* is the distance (i.e., the number of times we must go to its parent) from it to the root. This means in particular that the depth of a root is $0$.
17
17
- The *depth of a tree* is the greatest distance of its nodes.
18
-
- A *subtree* is the tree obtain by considering a particular node in a tree as the root of the tree made of its children.
18
+
- A *subtree* is the tree obtain by considering a particular node in a tree as the root of the tree made of all the nodes "below" it, starting with its children.
19
19
20
20
From there, operations generally include, as usual
21
21
22
22
- Creating an empty tree,
23
23
- Adding a node to a tree,
24
-
- Finding the smalles value in the tree,
25
-
- Removing a node from the tree,
24
+
- Finding the smallest value in the tree,
25
+
- Removing a node from the tree,
26
+
- etc.
26
27
27
-
<!--
28
-
### Abstract Data Type
28
+
In the following example:
29
29
30
-
### Difference with array
31
-
-->
30
+
!include diag/gra/bstree_example_1_with_depth.md
31
+
32
+
- The root has value 10,
33
+
- The root has two children, 7 and 11,
34
+
- The leaf with value 5 has $0$ children,
35
+
- The node with value 11 has one child (30): we call it "the right child", and observe that 11 has no "left child",
36
+
- The depth of the tree is 3,
37
+
- The nodes 7, 5 and 8 taken together form a subtree.
32
38
33
39
## Possible Implementation
34
40
35
41
### Binary Tree
36
42
37
-
We implement a binary tree class abstractly, because two methods will be missing: how to insert a value, and how to delete a value.
43
+
#### Node Class
44
+
45
+
Defining a `BTree` class start by defining a `Node` class:
46
+
47
+
```{download="./code/projects/Tree.zip"}
48
+
!include`snippetStart="// We begin by defining a node class.", snippetEnd="// We can now define the BTree class"` code/projects/Tree/Tree/BTree.cs
49
+
```
50
+
51
+
As we can see, a `Node` has three elements:
52
+
53
+
-`Data` is the value it is holding,
54
+
-`left` denotes its "left child",
55
+
-`right` denotes its "right child".
56
+
57
+
If we wanted to be more technically correct in our drawing, we would explicitly label some nodes as `null`, and the previous tree would actually be as follows:
58
+
59
+
!include diag/gra/bstree_example_1_with_null.md
60
+
61
+
#### Initializing
62
+
63
+
Then, a `BTree` object is simply … the `root``Node`, and we can construct, empty, and test for emptiness accordingly:
64
+
65
+
```{download="./code/projects/Tree.zip"}
66
+
!include`snippetStart="// are relying on the root Node.", snippetEnd="// We now look at how to"` code/projects/Tree/Tree/BTree.cs
67
+
```
68
+
69
+
#### Computing the Depth
70
+
71
+
Now, assume that we are given a `BTree` object. How can we compute its depth?
72
+
Its depth is the depth of the "deeper" node, but each node do not know their depth, only that they have 0, 1 or 2 children.
73
+
Of course, if the `BTree` is `null`, then deciding its depth is easy: it is $0$.
74
+
Then, the idea is that each node knows that its depth is $1$ more than the depth of its parent: remains to find which node has the biggest depth.
75
+
For this, we will use *recursion*.
76
+
77
+
In short, for a tree to determine its node, it needs to
78
+
79
+
- Have its `root` "ask its children" what their deepest node is,
80
+
- Take the maximum value returned.
81
+
82
+
For the `root`'s children to determine what the deepest node under them is, they need both to
83
+
84
+
- "Ask its children" what is their deepest node,
85
+
- Take the maximum value returned.
86
+
87
+
Etc., etc. Hence, we get:
88
+
89
+
```{download="./code/projects/Tree.zip"}
90
+
!include`snippetStart="// compute the Depth of a tree.", snippetEnd="// Finding is also recursive."` code/projects/Tree/Tree/BTree.cs
91
+
```
92
+
93
+
#### Displaying Trees
94
+
95
+
#### Implementation Detail
96
+
97
+
We implemented the binary tree class abstractly, because two methods are still missing: how to insert a value, and how to delete a value (we will add them later on).
98
+
This is the reason why we marked the `Node` class as `protected`, and not private: it will still be accessible by the class inheriting from `BTree`.
99
+
100
+
#### Finding a Value
101
+
38
102
We also mark the `Find` method as `virtual` because we will override it for something more efficient.
39
103
Note, finally, that we use the `protected` keyword, so that classes inheriting the `BTree` class will be able to manipulate `Node`s.
40
104
105
+
41
106
```{download="./code/projects/Tree.zip"}
42
-
!include code/projects/Tree/Tree/BTree.cs
107
+
!include`snippetStart="// Finding is also recursive.", snippetEnd="// Done with finding."` code/projects/Tree/Tree/BTree.cs
0 commit comments