Skip to content

Commit fc01840

Browse files
committed
adding matlab implementation to tree traversal
1 parent ed3ec56 commit fc01840

File tree

2 files changed

+164
-6
lines changed

2 files changed

+164
-6
lines changed
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
main()
2+
3+
%% Functions
4+
5+
function root = create_tree()
6+
node = @(k,v) containers.Map(k,v);
7+
8+
node2 = node(2, {{}}); node3 = node(3, {{}}); node4 = node(4, {{}});
9+
node6 = node(6, {{}}); node7 = node(7, {{}}); node8 = node(8, {{}});
10+
node10 = node(10, {{}}); node11 = node(11, {{}}); node12 = node(12, {{}});
11+
12+
node1 = node(1, {node2, node3, node4});
13+
node5 = node(5, {node6, node7, node8});
14+
node9 = node(9, {node10, node11, node12});
15+
16+
root = node(0, {node1, node5, node9});
17+
end
18+
19+
function root = create_btree()
20+
node = @(k,v) containers.Map(k,v);
21+
22+
node2 = node(2, {{}}); node3 = node(3, {{}});
23+
node5 = node(5, {{}}); node6 = node(6, {{}});
24+
25+
node1 = node(1, {node2, node3});
26+
node4 = node(4, {node5, node6});
27+
28+
root = node(0, {node1, node4});
29+
end
30+
31+
function DFS_recursive(n)
32+
33+
cell_index = @(a, b) a{b};
34+
ID = cell_index(keys(n), 1);
35+
36+
fprintf('%u ', ID);
37+
38+
children = cell_index(values(n), 1);
39+
for i = children
40+
child = i{1};
41+
if length(child)
42+
DFS_recursive(child);
43+
end
44+
end
45+
end
46+
47+
function DFS_recursive_postorder(n)
48+
49+
cell_index = @(a, b) a{b};
50+
51+
children = cell_index(values(n), 1);
52+
for i = children
53+
child = i{1};
54+
if length(child)
55+
DFS_recursive_postorder(child);
56+
end
57+
end
58+
59+
ID = cell_index(keys(n), 1);
60+
fprintf('%u ', ID);
61+
62+
end
63+
64+
function DFS_recursive_inorder_btree(n)
65+
66+
cell_index = @(a, b) a{b};
67+
ID = cell_index(keys(n), 1);
68+
children = cell_index(values(n), 1);
69+
70+
if length(children) == 2
71+
DFS_recursive_inorder_btree(children{1})
72+
fprintf('%u ', ID)
73+
DFS_recursive_inorder_btree(children{2})
74+
elseif length(children) == 1
75+
if length(children{1})
76+
DFS_recursive_inorder_btree(children{1})
77+
end
78+
fprintf('%u ', ID)
79+
else
80+
fprintf("Not a binary tree!")
81+
end
82+
end
83+
84+
function DFS_stack(n)
85+
86+
cell_index = @(a, b) a{b};
87+
node_stack = {n};
88+
89+
while length(node_stack) > 0
90+
91+
parent = node_stack{end};
92+
node_stack(end) = [];
93+
94+
ID = cell_index(keys(parent), 1);
95+
fprintf('%u ', ID);
96+
97+
children = cell_index(values(parent), 1);
98+
99+
for i = flip(children)
100+
child = i{1};
101+
if length(child)
102+
node_stack = {node_stack{:} child};
103+
end
104+
end
105+
end
106+
end
107+
108+
function BFS_queue(n)
109+
110+
cell_index = @(a, b) a{b};
111+
node_queue = {n};
112+
113+
while length(node_queue) > 0
114+
next_nodes = {};
115+
for parent_cell = node_queue
116+
parent = parent_cell{1};
117+
ID = cell_index(keys(parent), 1);
118+
fprintf('%u ', ID);
119+
children = cell_index(values(parent), 1);
120+
for i = children
121+
child = i{1};
122+
if length(child)
123+
next_nodes = {next_nodes{:}, child};
124+
end
125+
end
126+
end
127+
node_queue = next_nodes;
128+
end
129+
end
130+
131+
function main()
132+
root = create_tree();
133+
rootb = create_btree();
134+
135+
fprintf('\nDFS Recursive\n')
136+
DFS_recursive(root)
137+
138+
fprintf('\nDFS Recursive Postorder\n')
139+
DFS_recursive_postorder(root)
140+
141+
fprintf('\nDFS Recursive Inorder Binary Tree\n')
142+
DFS_recursive_inorder_btree(rootb)
143+
144+
fprintf('\nDFS Stack\n')
145+
DFS_stack(root)
146+
147+
fprintf('\nBFS Queue\n')
148+
BFS_queue(root)
149+
end

contents/tree_traversal/tree_traversal.md

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ As a note, a `node` struct is not necessary in javascript, so this is an example
3838
[import:24-27, lang:"asm-x64"](code/asm-x64/tree_traversal.s)
3939
{% sample lang="emojic" %}
4040
[import:1-3, lang:"emojicode"](code/emojicode/tree_traversal.emojic)
41+
{% sample lang="m" %}
42+
[import:6-6, lang:"matlab"](code/matlab/tree.m)
4143
{% endmethod %}
4244

4345
Because of this, the most straightforward way to traverse the tree might be recursive. This naturally leads us to the Depth-First Search (DFS) method:
@@ -77,6 +79,8 @@ Because of this, the most straightforward way to traverse the tree might be recu
7779
[import:290-314, lang:"asm-x64"](code/asm-x64/tree_traversal.s)
7880
{% sample lang="emojic" %}
7981
[import:27-34, lang:"emojicode"](code/emojicode/tree_traversal.emojic)
82+
{% sample lang="m" %}
83+
[import:31-45, lang:"matlab"](code/matlab/tree.m)
8084
{% endmethod %}
8185

8286
At least to me, this makes a lot of sense. We fight recursion with recursion! First, we first output the node we are on and then we call `DFS_recursive(...)` on each of its children nodes. This method of tree traversal does what its name implies: it goes to the depths of the tree first before going through the rest of the branches. In this case, the ordering looks like:
@@ -125,6 +129,8 @@ Now, in this case the first element searched through is still the root of the tr
125129
[import:316-344, lang:"asm-x64"](code/asm-x64/tree_traversal.s)
126130
{% sample lang="emojic" %}
127131
[import:36-43, lang:"emojicode"](code/emojicode/tree_traversal.emojic)
132+
{% sample lang="m" %}
133+
[import:47-62, lang:"matlab"](code/matlab/tree.m)
128134
{% endmethod %}
129135

130136
<p>
@@ -168,13 +174,10 @@ In this case, the first node visited is at the bottom of the tree and moves up t
168174
[import:346-396, lang:"asm-x64"](code/asm-x64/tree_traversal.s)
169175
{% sample lang="emojic" %}
170176
[import:45-62, lang:"emojicode"](code/emojicode/tree_traversal.emojic)
177+
{% sample lang="m" %}
178+
[import:64-82, lang:"matlab"](code/matlab/tree.m)
171179
{% endmethod %}
172180

173-
<p>
174-
<img class="center" src="res/DFS_in.png" width="500" />
175-
</p>
176-
177-
178181
The order here seems to be some mix of the other 2 methods and works through the binary tree from left to right.
179182

180183
Now, at this point, it might seem that the only way to search through a recursive data structure is with recursion, but this is not necessarily the case! Rather surprisingly, we can perform a DFS non-recursively by using a stack, which are data structures that hold multiple elements, but only allow you to interact with the very last element you put in. The idea here is simple:
@@ -221,12 +224,14 @@ In code, it looks like this:
221224
[import:398-445, lang:"asm-x64"](code/asm-x64/tree_traversal.s)
222225
{% sample lang="emojic" %}
223226
[import:64-79, lang:"emojicode"](code/emojicode/tree_traversal.emojic)
227+
{% sample lang="m" %}
228+
[import:84-106, lang:"matlab"](code/matlab/tree.m)
224229
{% endmethod %}
225230

226231
All this said, there are a few details about DFS that might not be ideal, depending on the situation. For example, if we use DFS on an incredibly long tree, we will spend a lot of time going further and further down a single branch without searching the rest of the data structure. In addition, it is not the natural way humans would order a tree if asked to number all the nodes from top to bottom. I would argue a more natural traversal order would look something like this:
227232

228233
<p>
229-
<img class="center" src="res/BFS_simple.png" width="500" />
234+
<img class="center" src="res/BFS_simple.png" width="500" />
230235
</p>
231236

232237
And this is exactly what Breadth-First Search (BFS) does! On top of that, it can be implemented in the same way as the `DFS_stack(...)` function above, simply by swapping the `stack` for a `queue`, which is similar to a stack, except that it only allows you to interact with the very first element instead of the last. In code, this looks something like:
@@ -266,6 +271,8 @@ And this is exactly what Breadth-First Search (BFS) does! On top of that, it can
266271
[import:447-498, lang:"asm-x64"](code/asm-x64/tree_traversal.s)
267272
{% sample lang="emojic" %}
268273
[import:81-96, lang:"emojicode"](code/emojicode/tree_traversal.emojic)
274+
{% sample lang="m" %}
275+
[import:108-129, lang:"matlab"](code/matlab/tree.m)
269276
{% endmethod %}
270277

271278
## Video Explanation
@@ -324,6 +331,8 @@ The code snippets were taken from this [Scratch project](https://scratch.mit.edu
324331
[import, lang:"asm-x64"](code/asm-x64/tree_traversal.s)
325332
{% sample lang="emojic" %}
326333
[import, lang:"emojicode"](code/emojicode/tree_traversal.emojic)
334+
{% sample lang="m" %}
335+
[import, lang:"matlab"](code/matlab/tree.m)
327336
{% endmethod %}
328337

329338

0 commit comments

Comments
 (0)