Add reference etc.

This commit is contained in:
Antti H S Laaksonen 2017-02-24 20:07:25 +02:00
parent a4d12103be
commit 92ad87112b
1 changed files with 39 additions and 28 deletions

View File

@ -562,9 +562,9 @@ is node 2:
\node[draw, circle] (3) at (-2,1) {$2$};
\node[draw, circle] (4) at (0,1) {$3$};
\node[draw, circle] (5) at (2,-1) {$7$};
\node[draw, circle] (6) at (-3,-1) {$5$};
\node[draw, circle, fill=lightgray] (6) at (-3,-1) {$5$};
\node[draw, circle] (7) at (-1,-1) {$6$};
\node[draw, circle] (8) at (-1,-3) {$8$};
\node[draw, circle, fill=lightgray] (8) at (-1,-3) {$8$};
\path[draw,thick,-] (1) -- (2);
\path[draw,thick,-] (1) -- (3);
\path[draw,thick,-] (1) -- (4);
@ -572,6 +572,9 @@ is node 2:
\path[draw,thick,-] (3) -- (6);
\path[draw,thick,-] (3) -- (7);
\path[draw,thick,-] (7) -- (8);
\path[draw=red,thick,->,line width=2pt] (6) edge [bend left] (3);
\path[draw=red,thick,->,line width=2pt] (8) edge [bend right=40] (3);
\end{tikzpicture}
\end{center}
@ -583,13 +586,17 @@ finding the lowest common ancestor of two nodes.
One way to solve the problem is to use the fact
that we can efficiently find the $k$th
ancestor of any node in the tree.
Thus, we can first make sure that
both nodes are at the same level in the tree,
and then find the smallest value of $k$
such that the $k$th ancestor of both nodes is the same.
Using this, we can divide the problem of
finding the lowest common ancestor into two parts.
As an example, let us find the lowest common
ancestor of nodes $5$ and $8$:
We use two pointers that initially point to the
two nodes for which we should find the
lowest common ancestor.
First, we move one of the pointers upwards
so that both nodes are at the same level in the tree.
In the example case, we move from node 8 to node 6,
after which both nodes are at the same level:
\begin{center}
\begin{tikzpicture}[scale=0.9]
@ -599,8 +606,8 @@ ancestor of nodes $5$ and $8$:
\node[draw, circle] (4) at (0,1) {$3$};
\node[draw, circle] (5) at (2,-1) {$7$};
\node[draw, circle,fill=lightgray] (6) at (-3,-1) {$5$};
\node[draw, circle] (7) at (-1,-1) {$6$};
\node[draw, circle,fill=lightgray] (8) at (-1,-3) {$8$};
\node[draw, circle,fill=lightgray] (7) at (-1,-1) {$6$};
\node[draw, circle] (8) at (-1,-3) {$8$};
\path[draw,thick,-] (1) -- (2);
\path[draw,thick,-] (1) -- (3);
\path[draw,thick,-] (1) -- (4);
@ -608,26 +615,30 @@ ancestor of nodes $5$ and $8$:
\path[draw,thick,-] (3) -- (6);
\path[draw,thick,-] (3) -- (7);
\path[draw,thick,-] (7) -- (8);
\path[draw=red,thick,->,line width=2pt] (8) edge [bend right] (7);
\end{tikzpicture}
\end{center}
Node $5$ is at level $3$, while node $8$ is at level $4$.
Thus, we first move one step upwards from node $8$ to node $6$.
After this, it turns out that the parent of both nodes $5$
and $6$ is node $2$, so we have found the lowest common ancestor.
After this, we determine the minimum number of steps
needed to move both pointers upwards so that
they will point to the same node.
This node is the lowest common ancestor of the nodes.
The following picture shows how we move in the tree:
In the example case, it suffices to move both pointers
one step upwards to node 2,
which is the lowest common ancestor:
\begin{center}
\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,fill=lightgray] (3) at (-2,1) {$2$};
\node[draw, circle] (4) at (0,1) {$3$};
\node[draw, circle] (5) at (2,-1) {$7$};
\node[draw, circle,fill=lightgray] (6) at (-3,-1) {$5$};
\node[draw, circle] (6) at (-3,-1) {$5$};
\node[draw, circle] (7) at (-1,-1) {$6$};
\node[draw, circle,fill=lightgray] (8) at (-1,-3) {$8$};
\node[draw, circle] (8) at (-1,-3) {$8$};
\path[draw,thick,-] (1) -- (2);
\path[draw,thick,-] (1) -- (3);
\path[draw,thick,-] (1) -- (4);
@ -637,15 +648,14 @@ The following picture shows how we move in the tree:
\path[draw,thick,-] (7) -- (8);
\path[draw=red,thick,->,line width=2pt] (6) edge [bend left] (3);
\path[draw=red,thick,->,line width=2pt] (8) edge [bend right] (7);
\path[draw=red,thick,->,line width=2pt] (7) edge [bend right] (3);
\end{tikzpicture}
\end{center}
Using this method, we can find the lowest common ancestor
of any two nodes in $O(\log n)$ time after an $O(n \log n)$ time
preprocessing, because both steps can be
performed in $O(\log n)$ time.
Since both parts of the algorithm can be performed in
$O(\log n)$ time using precomputed information,
we can find the lowest common ancestor of any two
nodes in $O(\log n)$ time using this technique.
\subsubsection{Method 2}
@ -689,13 +699,14 @@ using a depth-first search:
\end{tikzpicture}
\end{center}
However, we use a bit different variant of
the tree traversal array where
However, we use a bit different tree
traversal array than before:
we add each node to the array \emph{always}
when the depth-first search visits the node,
and not only at the first visit.
when the depth-first search walks through the node,
and not only at the first visit\footnote{A similar technique is sometimes called the
\key{Euler tour technique} \cite{tar84}.}.
Hence, a node that has $k$ children appears $k+1$ times
in the array, and there are a total of $2n-1$
in the array and there are a total of $2n-1$
nodes in the array.
We store two values in the array: