-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
087f14a
commit af66a3d
Showing
3 changed files
with
233 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
# All longest paths | ||
|
||
Our next problem is to calculate for every node | ||
in the tree the maximum length of a path | ||
that begins at the node. | ||
This can be seen as a generalization of the | ||
tree diameter problem, because the largest of those | ||
lengths equals the diameter of the tree. | ||
Also this problem can be solved in $O(n)$ time. | ||
|
||
As an example, consider the following tree: | ||
|
||
<script type="text/tikz"> | ||
\begin{tikzpicture}[scale=0.9] | ||
\node[draw, circle] (1) at (0,0) {1}; | ||
\node[draw, circle] (2) at (-1.5,-1) {4}; | ||
\node[draw, circle] (3) at (2,0) {2}; | ||
\node[draw, circle] (4) at (-1.5,1) {3}; | ||
\node[draw, circle] (6) at (3.5,-1) {6}; | ||
\node[draw, circle] (7) at (3.5,1) {5}; | ||
\path[draw,thick,-] (1) -- (2); | ||
\path[draw,thick,-] (1) -- (3); | ||
\path[draw,thick,-] (1) -- (4); | ||
\path[draw,thick,-] (3) -- (6); | ||
\path[draw,thick,-] (3) -- (7); | ||
\end{tikzpicture} | ||
</script> | ||
|
||
Let `maxLength(x)` denote the maximum length | ||
of a path that begins at node $x$. | ||
For example, in the above tree, | ||
`maxLength(4)=3`, because there | ||
is a path $4 \rightarrow 1 \rightarrow 2 \rightarrow 6$. | ||
Here is a complete table of the values: | ||
|
||
| | | | | | | | | ||
|-|-|-|-|-|-|-| | ||
| node $x$ | 1 | 2 | 3 | 4 | 5 | 6 | | ||
| maxLength($x$) | 2 | 2 | 3 | 3 | 3 | 3 | | ||
|
||
Also in this problem, a good starting point | ||
for solving the problem is to root the tree arbitrarily: | ||
|
||
<script type="text/tikz"> | ||
\begin{tikzpicture}[scale=0.9] | ||
\node[draw, circle] (1) at (0,3) {1}; | ||
\node[draw, circle] (2) at (2,1) {4}; | ||
\node[draw, circle] (3) at (-2,1) {2}; | ||
\node[draw, circle] (4) at (0,1) {3}; | ||
\node[draw, circle] (6) at (-3,-1) {5}; | ||
\node[draw, circle] (7) at (-1,-1) {6}; | ||
\path[draw,thick,-] (1) -- (2); | ||
\path[draw,thick,-] (1) -- (3); | ||
\path[draw,thick,-] (1) -- (4); | ||
\path[draw,thick,-] (3) -- (6); | ||
\path[draw,thick,-] (3) -- (7); | ||
\end{tikzpicture} | ||
</script> | ||
|
||
The first part of the problem is to calculate for every node $x$ | ||
the maximum length of a path that goes through a child of $x$. | ||
For example, the longest path from node 1 | ||
goes through its child 2: | ||
|
||
<script type="text/tikz"> | ||
\begin{tikzpicture}[scale=0.9] | ||
\node[draw, circle] (1) at (0,3) {1}; | ||
\node[draw, circle] (2) at (2,1) {4}; | ||
\node[draw, circle] (3) at (-2,1) {2}; | ||
\node[draw, circle] (4) at (0,1) {3}; | ||
\node[draw, circle] (6) at (-3,-1) {5}; | ||
\node[draw, circle] (7) at (-1,-1) {6}; | ||
\path[draw,thick,-] (1) -- (2); | ||
\path[draw,thick,-] (1) -- (3); | ||
\path[draw,thick,-] (1) -- (4); | ||
\path[draw,thick,-] (3) -- (6); | ||
\path[draw,thick,-] (3) -- (7); | ||
|
||
\path[draw,thick,->,color=red,line width=2pt] (1) -- (3); | ||
\path[draw,thick,->,color=red,line width=2pt] (3) -- (6); | ||
\end{tikzpicture} | ||
</script> | ||
|
||
This part is easy to solve in $O(n)$ time, because we can use | ||
dynamic programming as we have done previously. | ||
|
||
Then, the second part of the problem is to calculate | ||
for every node $x$ the maximum length of a path | ||
through its parent $p$. | ||
For example, the longest path | ||
from node 3 goes through its parent 1: | ||
|
||
<script type="text/tikz"> | ||
\begin{tikzpicture}[scale=0.9] | ||
\node[draw, circle] (1) at (0,3) {1}; | ||
\node[draw, circle] (2) at (2,1) {4}; | ||
\node[draw, circle] (3) at (-2,1) {2}; | ||
\node[draw, circle] (4) at (0,1) {3}; | ||
\node[draw, circle] (6) at (-3,-1) {5}; | ||
\node[draw, circle] (7) at (-1,-1) {6}; | ||
\path[draw,thick,-] (1) -- (2); | ||
\path[draw,thick,-] (1) -- (3); | ||
\path[draw,thick,-] (1) -- (4); | ||
\path[draw,thick,-] (3) -- (6); | ||
\path[draw,thick,-] (3) -- (7); | ||
|
||
\path[draw,thick,->,color=red,line width=2pt] (4) -- (1); | ||
\path[draw,thick,->,color=red,line width=2pt] (1) -- (3); | ||
\path[draw,thick,->,color=red,line width=2pt] (3) -- (6); | ||
\end{tikzpicture} | ||
</script> | ||
|
||
At first glance, it seems that we should choose | ||
the longest path from $p$. | ||
However, this _does not_ always work, | ||
because the longest path from $p$ | ||
may go through $x$. | ||
Here is an example of this situation: | ||
|
||
<script type="text/tikz"> | ||
\begin{tikzpicture}[scale=0.9] | ||
\node[draw, circle] (1) at (0,3) {1}; | ||
\node[draw, circle] (2) at (2,1) {4}; | ||
\node[draw, circle] (3) at (-2,1) {2}; | ||
\node[draw, circle] (4) at (0,1) {3}; | ||
\node[draw, circle] (6) at (-3,-1) {5}; | ||
\node[draw, circle] (7) at (-1,-1) {6}; | ||
\path[draw,thick,-] (1) -- (2); | ||
\path[draw,thick,-] (1) -- (3); | ||
\path[draw,thick,-] (1) -- (4); | ||
\path[draw,thick,-] (3) -- (6); | ||
\path[draw,thick,-] (3) -- (7); | ||
|
||
\path[draw,thick,->,color=red,line width=2pt] (3) -- (1); | ||
\path[draw,thick,->,color=red,line width=2pt] (1) -- (2); | ||
\end{tikzpicture} | ||
</script> | ||
|
||
Still, we can solve the second part in | ||
$O(n)$ time by storing _two_ maximum lengths | ||
for each node $x$: | ||
|
||
- `maxLength_1(x)`: the maximum length of a path from $x$ | ||
- `maxLength_2(x)`: the maximum length of a path from $x$ in another direction than the first path | ||
|
||
For example, in the above graph, | ||
`maxLength_1(1)=2` using the path $1 \rightarrow 2 \rightarrow 5$, | ||
and `maxLength_2(1)=1` using the path $1 \rightarrow 3$. | ||
|
||
Finally, if the path that corresponds to | ||
`maxLength_1(p)` goes through $x$, | ||
we conclude that the maximum length is | ||
`maxLength_2(p)+1`, | ||
and otherwise the maximum length is | ||
`maxLength_1(p)+1`. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
# Binary trees | ||
|
||
A **binary tree** is a rooted tree | ||
where each node has a left and right subtree. | ||
It is possible that a subtree of a node is empty. | ||
Thus, every node in a binary tree has | ||
zero, one or two children. | ||
|
||
For example, the following tree is a binary tree: | ||
|
||
<script type="text/tikz"> | ||
\begin{tikzpicture}[scale=0.9] | ||
\node[draw, circle] (1) at (0,0) {1}; | ||
\node[draw, circle] (2) at (-1.5,-1.5) {2}; | ||
\node[draw, circle] (3) at (1.5,-1.5) {3}; | ||
\node[draw, circle] (4) at (-3,-3) {4}; | ||
\node[draw, circle] (5) at (0,-3) {5}; | ||
\node[draw, circle] (6) at (-1.5,-4.5) {6}; | ||
\node[draw, circle] (7) at (3,-3) {7}; | ||
|
||
\path[draw,thick,-] (1) -- (2); | ||
\path[draw,thick,-] (1) -- (3); | ||
\path[draw,thick,-] (2) -- (4); | ||
\path[draw,thick,-] (2) -- (5); | ||
\path[draw,thick,-] (5) -- (6); | ||
\path[draw,thick,-] (3) -- (7); | ||
\end{tikzpicture} | ||
</script> | ||
|
||
The nodes of a binary tree have three natural | ||
orderings that correspond to different ways to | ||
recursively traverse the tree: | ||
|
||
- **pre-order**: first process the root, | ||
then traverse the left subtree, then traverse the right subtree | ||
- **in-order**: first traverse the left subtree, | ||
then process the root, then traverse the right subtree | ||
- **post-order**: first traverse the left subtree, | ||
then traverse the right subtree, then process the root | ||
|
||
For the above tree, the nodes in | ||
pre-order are | ||
\\([1,2,4,5,6,3,7]\\), | ||
in in-order \\([4,2,6,5,1,3,7]\\) | ||
and in post-order \\([4,6,5,2,7,3,1]\\). | ||
|
||
If we know the pre-order and in-order | ||
of a tree, we can reconstruct the exact structure of the tree. | ||
For example, the above tree is the only possible tree | ||
with pre-order \\([1,2,4,5,6,3,7]\\) and | ||
in-order \\([4,2,6,5,1,3,7]\\). | ||
In a similar way, the post-order and in-order | ||
also determine the structure of a tree. | ||
|
||
However, the situation is different if we only know | ||
the pre-order and post-order of a tree. | ||
In this case, there may be more than one tree | ||
that match the orderings. | ||
For example, in both of the trees | ||
|
||
<script type="text/tikz"> | ||
\begin{tikzpicture}[scale=0.9] | ||
\node[draw, circle] (1) at (0,0) {1}; | ||
\node[draw, circle] (2) at (-1.5,-1.5) {2}; | ||
\path[draw,thick,-] (1) -- (2); | ||
|
||
\node[draw, circle] (1b) at (0+4,0) {1}; | ||
\node[draw, circle] (2b) at (1.5+4,-1.5) {2}; | ||
\path[draw,thick,-] (1b) -- (2b); | ||
\end{tikzpicture} | ||
</script> | ||
|
||
the pre-order is \\([1, 2]\\) and the post-order is \\([2, 1]\\), but the structures of the trees are different | ||
|
||
|