Skip to content

Commit 982b7c6

Browse files
committed
Improving notes on BSTrees.
1 parent b3081c8 commit 982b7c6

5 files changed

Lines changed: 49 additions & 42 deletions

File tree

source/code/projects/Tree/Tree/BSTree.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,19 @@ private Node Insert(T dataP, Node nodeP)
3333
return nodeP;
3434
}
3535

36-
public override bool Find(T dataP)
37-
{
38-
bool found = false;
39-
if (root != null)
36+
// Finding into a BSTree
37+
38+
public override bool Find(T dataP)
4039
{
41-
found = Find(root, dataP);
40+
bool found = false;
41+
if (root != null)
42+
{
43+
found = Find(root, dataP);
44+
}
45+
return found;
4246
}
43-
return found;
44-
}
45-
46-
// Finding into a BSTree
4747

48-
private bool Find(Node nodeP, T dataP)
48+
private bool Find(Node nodeP, T dataP)
4949
{
5050
bool found = false;
5151
if (nodeP != null)

source/code/projects/Tree/Tree/BTree.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@ public Node(
2121
left = leftP;
2222
right = rightP;
2323
}
24-
24+
// Displaying a Node is only
25+
// displaying its data.
2526
public override string ToString()
2627
{
27-
return "| " + Data.ToString() + " |";
28+
return Data.ToString();
2829
}
2930
}
3031

@@ -90,9 +91,9 @@ private int Depth(Node nodeP, int depth)
9091
depthR = Depth(nodeP.right, result + 1);
9192
}
9293
// Finally, if at least one sub-tree
93-
// is not null, we take their max to
94-
// be the depth of the tree starting
95-
// with our current node.
94+
// is not null, we take the max of their
95+
// depths to be the depth of the tree
96+
// starting with our current node.
9697
if (nodeP.left != null || nodeP.right != null)
9798
{
9899
result = Math.Max(depthL, depthR);
@@ -211,7 +212,10 @@ private string TraversePo(Node nodeP)
211212
public abstract void Insert(T dataP);
212213
public abstract bool Delete(T dataP);
213214

214-
// The ToString method is simply here to help debug.
215+
// The ToString method is simply here to help us debug.
216+
// It is not really pretty, but using pre-order and spaces
217+
// to make it easier to understand how the tree is
218+
// constructed. It also displays the depth of the tree.
215219

216220
public override string ToString()
217221
{

source/diag/gra/bstree_example_2.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
%%% A simple binary tree illustrating that insertion order matter
1+
%%% The binary tree obtained by inserting 10, 6, 13, 12 and 14 (in that order).
22

33
A((10))-->B((6))
44
A-->C((13))

source/diag/gra/bstree_example_3.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
%%% A simple binary tree illustrating that insertion order matter
1+
%%% The binary tree obtained by inserting 14, 12, 13, 6 and 10 (in that order).
22

33
A((14))-->B((12))
44
A~~~H0:::hidden

source/lectures/data/trees.md

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,38 +10,38 @@ tags:
1010
A [binary tree](https://en.wikipedia.org/wiki/Binary_tree) is a precise mathematical concept that can be defined as a restriction on graphs.
1111
As an abstract data type, it generally uses the following definitions:
1212

13-
- A binary tree is made of *nodes*, each of which contain *one value*, can have up to 2 *children*.
13+
- A binary tree is made of *nodes*, each of which holds *one value*, can have up to 2 *children*.
1414
- 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-
- 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. This means in particular that the depth of a root is $0$.
17-
- The *depth of a tree* is the greatest distance of its nodes.
15+
- A node without children is called *a leaf*.
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 the root is $0$.
17+
- The *depth of a tree* is the maximum depth of the nodes it contain.
1818
- 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.
1919

2020
From there, operations generally include, as usual
2121

2222
- Creating an empty tree,
2323
- Adding a node to a tree,
2424
- Finding the smallest value in the tree,
25-
- Removing a node from the tree,
25+
- Removing a node holding a specific value from the tree,
2626
- etc.
2727

2828
In the following example:
2929

3030
!include diag/gra/bstree_example_1_with_depth.md
3131

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 (with value 30): we call it "the right child", and observe that 11 has no "left child",
32+
- The root holds the value 10,
33+
- The root has two children, holding the values 7 and 11,
34+
- The node holding the value 5 has $0$ children, hence it is a leaf,
35+
- The node with value 11 has one child (holding the value 30): we call it "the right child", and observe that the node holding the value 11 has no "left child",
3636
- The depth of the tree is $4$,
37-
- The nodes 7, 5 and 8 taken together form a subtree, of depth $1$.
37+
- The nodes holding the values 7, 5 and 8 taken together form a subtree, of depth $1$.
3838

3939
## Possible Implementation
4040

4141
### Binary Tree
4242

4343
We implemented the binary tree class abstractly, because two methods will be missing at the beginning: how to insert a value, and how to delete a value (we will add them later on, in a class that will inherit from this `BTree` class).
44-
This is the reason why we mark the `Node` class as `protected` below, and not private: it will still be accessible by the class inheriting from `BTree`.
44+
This is the reason why we mark the `Node` class as `protected` below, and not `private`: it will still be accessible by the class inheriting from `BTree`.
4545

4646
#### Node Class
4747

@@ -63,18 +63,20 @@ If we wanted to be more technically correct in our drawing, we would explicitly
6363

6464
#### Initializing
6565

66-
A `BTree` object is simply the `root` `Node`, and we can construct, empty, and test for emptiness accordingly:
66+
A `BTree` object is simply the `root` `Node`, and we can construct, empty, and test for emptiness accordingly:
6767

6868
```{download="./code/projects/Tree.zip"}
6969
!include`snippetStart="// are relying on the root Node.", snippetEnd="// We now look at how to"` code/projects/Tree/Tree/BTree.cs
7070
```
7171

72-
#### Computing the Depth
72+
#### Computing the Depth of the tree
7373

7474
Now, assume that we are given a `BTree` object. How can we compute its depth?
75-
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.
76-
Of course, if the `BTree` is `null`, then deciding its depth is easy: it is $0$.
77-
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+
Its depth is the maximum depth of the nodes it contain.
76+
However, only the root knows its depth (it is $0$), all the other nodes do not know their depth, only that they have 0, 1 or 2 children.
77+
78+
Of course, if the `BTree` is `null` or if its `root` has $0$ children, then deciding its depth is easy: it is $0$.
79+
Otherwise, the idea is that each tree knows that its depth is $1$ more than the depth of the its two sub-trees: remains to find which sub-tree has the biggest depth.
7880
For this, we will use *recursion*.
7981

8082
In short, for a tree to determine its node, it needs to
@@ -93,21 +95,21 @@ Etc., etc. Hence, we get:
9395
!include`snippetStart="// compute the Depth of a tree.", snippetEnd="// Finding is also recursive."` code/projects/Tree/Tree/BTree.cs
9496
```
9597

96-
Note that we have *two* recursive calls: one for the `left` `Node`, one for the `right` `Node` (if they are not empty).
98+
Note that we have *two* recursive calls: one for the `left` `Node`, one for the `right` `Node` (if they are not `null`).
9799

98100
#### Displaying Trees
99101

100-
There are essentially three ways of "linearizing" a tree (that is, listing its value as a list), depending how we organize the recursive calls.
102+
There are essentially three ways of "linearizing" a tree (that is, listing its value in a sequence), depending how we organize the recursive calls.
101103

102104
- *Inorder* traversal displays
103105
- First the left sub-tree,
104-
- Secondly the data of the current node,
106+
- Secondly the data held by the current node,
105107
- Thirdly the right sub-tree.
106108

107109
For our recurring example, we obtain "5 7 8 10 11 12 15 30".
108110

109111
- *Preorder* traversal displays
110-
- First the data of the current node,
112+
- First the data held by the current node,
111113
- Secondly the left sub-tree,
112114
- Thirdly the right sub-tree.
113115

@@ -116,7 +118,7 @@ There are essentially three ways of "linearizing" a tree (that is, listing its v
116118
- *Postorder* traversal displays
117119
- First the left sub-tree,
118120
- Secondly the right sub-tree,
119-
- Thirdly the data of the current node.
121+
- Thirdly the data held by the current node.
120122

121123
For our recurring example, we obtain "5 8 7 15 12 30 11 10".
122124

@@ -154,7 +156,7 @@ A binary *search* tree (BST) is a specific type of binary tree that ensures that
154156
- each node's value is less than all the values stored in its right subtree,
155157
- a value cannot occur twice.
156158

157-
Our example is a binary search thee:
159+
Our recurring example happens to be a binary search tree:
158160

159161
- All the values "to the left of" the root are less than $10$,
160162
- All the values "to the right of" the root are greater than $10$,
@@ -163,10 +165,11 @@ Our example is a binary search thee:
163165
- etc.
164166

165167
Note that this is the reason why the node with value $30$ is drawn "to the right of" the node with value $11$: we always need to make the difference between left and right children, even if there is only one child.
168+
A tree almost identical to our recurring example, but where $30$ was at the right of the node holding the value $11$ would not be a binary *search* tree, but simply a binary tree.
166169

167170
#### Implementation detail
168171

169-
Note that since we need to be able to compare our values, we must tell C# that we will not just be using any `T` generic type, but a type that realizes the [IComparable](https://learn.microsoft.com/en-us/dotnet/api/system.icomparable-1?view=net-9.0) interface.
172+
Note that since we need to be able to compare our values, we must tell C# that we will not just be using any generic type `T`, but a type that realizes the [IComparable](https://learn.microsoft.com/en-us/dotnet/api/system.icomparable-1?view=net-9.0) interface.
170173
This forces `T` to have a `CompareTo` method, that we will use to compare the data held by the nodes as follows:
171174

172175
```
@@ -178,7 +181,7 @@ will return
178181
- a value less than $0$ if `dataP < nodeP.Data`,
179182
- a value greater than $0$ if `dataP > nodeP.Data`.
180183

181-
Similarly to the `Equals` method, this is because the `>` and `<` operators are not overloaded by default, so we must use this more convoluted way of determining if `dataP` is less than or greater than `nodeP.Data`. Of course, if neither is `true`, it means that `dataP` is equl to `nodeP.Data`.
184+
Similarly to the `Equals` method, this is because the `>` and `<` operators are not overloaded by default, so we must use this more convoluted way of determining if `dataP` is less than or greater than `nodeP.Data`. Of course, if neither is `true`, it means that `dataP` is equal to `nodeP.Data`.
182185

183186
#### Insertion
184187

0 commit comments

Comments
 (0)