Chapter 14 first version
This commit is contained in:
parent
a0f2d60b2b
commit
f1011ab0f6
408
luku14.tex
408
luku14.tex
|
@ -1,16 +1,16 @@
|
|||
\chapter{Puiden käsittely}
|
||||
\chapter{Tree algorithms}
|
||||
|
||||
\index{puu@puu}
|
||||
\index{tree}
|
||||
|
||||
\key{Puu} on yhtenäinen, syklitön verkko,
|
||||
jossa on $n$ solmua ja $n-1$ kaarta.
|
||||
Jos puusta poistaa yhden kaaren, se ei ole enää yhtenäinen,
|
||||
ja jos puuhun lisää yhden kaaren, se ei ole enää syklitön.
|
||||
Puussa pätee myös aina, että
|
||||
jokaisen kahden puun solmun välillä on yksikäsitteinen polku.
|
||||
|
||||
Esimerkiksi seuraavassa puussa on 7 solmua ja 6 kaarta:
|
||||
A \key{tree} is a connected, acyclic graph
|
||||
that contains $n$ nodes and $n-1$ edges.
|
||||
Removing any edge from a tree divides it
|
||||
into two components,
|
||||
and adding any edge to a tree creates a cycle.
|
||||
Moreover, there is always a unique path between any
|
||||
two nodes in a tree.
|
||||
|
||||
For example, the following tree contains 7 nodes and 6 edges:
|
||||
\begin{center}
|
||||
\begin{tikzpicture}[scale=0.9]
|
||||
\node[draw, circle] (1) at (0,3) {$1$};
|
||||
|
@ -29,21 +29,21 @@ Esimerkiksi seuraavassa puussa on 7 solmua ja 6 kaarta:
|
|||
\end{tikzpicture}
|
||||
\end{center}
|
||||
|
||||
\index{lehti@lehti}
|
||||
\index{leaf}
|
||||
|
||||
Puun \key{lehdet} ovat solmut,
|
||||
joiden aste on 1 eli joista lähtee vain yksi kaari.
|
||||
Esimerkiksi yllä olevan puun lehdet ovat
|
||||
solmut 3, 5, 6 ja 7.
|
||||
The \key{leaves} of a tree are nodes
|
||||
with degree 1, i.e., with only one neighbor.
|
||||
For example, the leaves in the above tree
|
||||
are nodes 3, 5, 6 and 7.
|
||||
|
||||
\index{juuri@juuri}
|
||||
\index{juurellinen puu@juurellinen puu}
|
||||
\index{root}
|
||||
\index{rooted tree}
|
||||
|
||||
Jos puu on \key{juurellinen}, yksi solmuista
|
||||
on puun \key{juuri},
|
||||
jonka alapuolelle muut solmut asettuvat.
|
||||
Esimerkiksi jos yllä olevassa puussa valitaan
|
||||
juureksi solmu 1, solmut asettuvat seuraavaan järjestykseen:
|
||||
In a \key{rooted} tree, one of the nodes
|
||||
is chosen to be a \key{root}, and all other nodes are
|
||||
placed underneath the root.
|
||||
For example, in the following tree,
|
||||
node 1 is the root of the tree.
|
||||
|
||||
\begin{center}
|
||||
\begin{tikzpicture}[scale=0.9]
|
||||
|
@ -63,84 +63,82 @@ juureksi solmu 1, solmut asettuvat seuraavaan järjestykseen:
|
|||
\end{tikzpicture}
|
||||
\end{center}
|
||||
|
||||
\index{lapsi@lapsi}
|
||||
\index{vanhempi@vanhempi}
|
||||
\index{child}
|
||||
\index{parent}
|
||||
|
||||
Juurellisessa puussa solmun \key{lapset}
|
||||
ovat sen alemman tason naapurit
|
||||
ja solmun \key{vanhempi}
|
||||
on sen ylemmän tason naapuri.
|
||||
Jokaisella solmulla on tasan yksi vanhempi,
|
||||
paitsi juurella ei ole vanhempaa.
|
||||
Esimerkiksi yllä olevassa puussa solmun 4
|
||||
lapset ovat solmut 3 ja 7 ja solmun 4 vanhempi on solmu 1.
|
||||
In a rooted tree, the \key{childern} of a node
|
||||
are its lower neighbors, and the \key{parent} of a node
|
||||
is its upper neighbor.
|
||||
Each node has exactly one parent,
|
||||
except that the root doesn't have a parent.
|
||||
For example, in the above tree,
|
||||
the childern of node 4 are nodes 3 and 7,
|
||||
and the parent is node 1.
|
||||
|
||||
\index{alipuu@alipuu}
|
||||
\index{subtree}
|
||||
|
||||
Juurellisen puun rakenne on \emph{rekursiivinen}:
|
||||
jokaisesta puun solmusta alkaa \key{alipuu},
|
||||
jonka juurena on solmu itse ja johon kuuluvat
|
||||
kaikki solmut, joihin solmusta pääsee kulkemalla alaspäin puussa.
|
||||
Esimerkiksi solmun 4 alipuussa
|
||||
ovat solmut 4, 3 ja 7.
|
||||
The structure of a rooted tree is \emph{recursive}:
|
||||
each node in the tree is the root of a \key{subtree}
|
||||
that contains the node itself and all other nodes
|
||||
that can be reached by travelling downwards in the tree.
|
||||
For example, in the above tree, the subtree of node 4
|
||||
contains nodes 4, 3 and 7.
|
||||
|
||||
\section{Puun läpikäynti}
|
||||
\section{Tree search}
|
||||
|
||||
Puun läpikäyntiin voi käyttää syvyyshakua ja
|
||||
leveyshakua samaan
|
||||
tapaan kuin yleisen verkon läpikäyntiin.
|
||||
Erona on kuitenkin, että puussa ei ole silmukoita,
|
||||
minkä ansiosta ei tarvitse huolehtia siitä,
|
||||
että läpikäynti päätyisi tiettyyn
|
||||
solmuun monesta eri suunnasta.
|
||||
Depth-first search and breadth-first search
|
||||
can be used for going through the nodes in a tree.
|
||||
However, the search is easier to implement than
|
||||
for a general graph, because
|
||||
there are no cycles in the tree, and it is not
|
||||
possible that the search would visit a node several times.
|
||||
|
||||
Tavallisin menetelmä puun läpikäyntiin on
|
||||
valita tietty solmu juureksi ja aloittaa
|
||||
siitä syvyyshaku.
|
||||
Seuraava rekursiivinen funktio toteuttaa sen:
|
||||
Often, we start a depth-first search from a chosen
|
||||
root node.
|
||||
The following recursive function implements it:
|
||||
|
||||
\begin{lstlisting}
|
||||
void haku(int s, int e) {
|
||||
// solmun s käsittely tähän
|
||||
void dfs(int s, int e) {
|
||||
// process node s
|
||||
for (auto u : v[s]) {
|
||||
if (u != e) haku(u, s);
|
||||
if (u != e) dfs(u, s);
|
||||
}
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
Funktion parametrit ovat käsiteltävä solmu $s$
|
||||
sekä edellinen käsitelty solmu $e$.
|
||||
Parametrin $e$ ideana on varmistaa, että
|
||||
läpikäynti etenee vain alaspäin puussa
|
||||
sellaisiin solmuihin, joita ei ole vielä käsitelty.
|
||||
The function parameters are the current node $s$
|
||||
and the previous node $e$.
|
||||
The idea of the parameter $e$ is to ensure
|
||||
that the search only proceeds downwards in the tree
|
||||
towards nodes that have not been visited yet.
|
||||
|
||||
Seuraava kutsu käy läpi puun aloittaen juuresta $x$:
|
||||
The following function call starts the search
|
||||
at node $x$:
|
||||
|
||||
\begin{lstlisting}
|
||||
haku(x, 0);
|
||||
dfs(x, 0);
|
||||
\end{lstlisting}
|
||||
|
||||
Ensimmäisessä kutsussa $e=0$, koska läpikäynti
|
||||
saa edetä juuresta kaikkiin suuntiin alaspäin.
|
||||
In the first call $e=0$ because there is no
|
||||
previous node, and it is allowed
|
||||
to proceed to any direction in the tree.
|
||||
|
||||
\subsubsection{Dynaaminen ohjelmointi}
|
||||
\subsubsection{Dynamic programming}
|
||||
|
||||
Puun läpikäyntiin voi myös yhdistää dynaamista
|
||||
ohjelmointia ja laskea sen avulla jotakin tietoa puusta.
|
||||
Dynaamisen ohjelmoinnin avulla voi esimerkiksi
|
||||
laskea ajassa $O(n)$ jokaiselle solmulle,
|
||||
montako solmua sen alipuussa
|
||||
on tai kuinka pitkä on pisin solmusta
|
||||
alaspäin jatkuva polku puussa.
|
||||
We can also use dynamic programming to calculate
|
||||
some information from the tree during the search.
|
||||
Using dynamic programming, we can, for example,
|
||||
calculate in $O(n)$ time for each node the
|
||||
number of nodes in its subtree,
|
||||
or the length of the longest path downwards
|
||||
that begins at the node.
|
||||
|
||||
Lasketaan esimerkiksi jokaiselle solmulle $s$
|
||||
sen alipuun solmujen määrä $\texttt{c}[s]$.
|
||||
Solmun alipuuhun kuuluvat solmu itse
|
||||
sekä kaikki sen lasten alipuut.
|
||||
Niinpä solmun alipuun solmujen määrä on
|
||||
yhden suurempi kuin summa lasten
|
||||
alipuiden solmujen määristä.
|
||||
Laskennan voi toteuttaa seuraavasti:
|
||||
As an example, let's calculate for each node $s$
|
||||
a value $\texttt{c}[s]$: the number of nodes in its subtree.
|
||||
The subtree contains the node itself and
|
||||
all nodes in the subtrees of its children.
|
||||
Thus, we can calculate the number of nodes
|
||||
recursively using the following code:
|
||||
|
||||
\begin{lstlisting}
|
||||
void haku(int s, int e) {
|
||||
|
@ -153,13 +151,14 @@ void haku(int s, int e) {
|
|||
}
|
||||
\end{lstlisting}
|
||||
|
||||
\section{Läpimitta}
|
||||
\section{Diameter}
|
||||
|
||||
\index{lzpimitta@läpimitta}
|
||||
\index{diameter}
|
||||
|
||||
Puun \key{läpimitta} on pisin polku
|
||||
kahden puussa olevan solmun välillä.
|
||||
Esimerkiksi puussa
|
||||
The \key{diameter} of a tree
|
||||
is the length of the longest path
|
||||
between two nodes in the tree.
|
||||
For example, in the tree
|
||||
\begin{center}
|
||||
\begin{tikzpicture}[scale=0.9]
|
||||
\node[draw, circle] (1) at (0,3) {$1$};
|
||||
|
@ -177,33 +176,28 @@ Esimerkiksi puussa
|
|||
\path[draw,thick,-] (3) -- (7);
|
||||
\end{tikzpicture}
|
||||
\end{center}
|
||||
läpimitta on 4, jota vastaa kaksi polkua:
|
||||
solmujen 3 ja 6 välinen polku sekä
|
||||
solmujen 7 ja 6 välinen polku.
|
||||
the diameter is 4, and it corresponds to two paths:
|
||||
the path between nodes 3 and 6,
|
||||
and the path between nodes 7 and 6.
|
||||
|
||||
Käymme seuraavaksi läpi kaksi tehokasta
|
||||
algoritmia puun läpimitan laskeminen.
|
||||
Molemmat algoritmit laskevat läpimitan ajassa
|
||||
$O(n)$.
|
||||
Ensimmäinen algoritmi perustuu dynaamiseen
|
||||
ohjelmointiin, ja toinen algoritmi
|
||||
laskee läpimitan kahden syvyyshaun avulla.
|
||||
Next we will learn two efficient algorithms
|
||||
for calculating the diameter of a tree.
|
||||
Both algorithms calculate the diameter in $O(n)$ time.
|
||||
The first algorithm is based on dynamic programming,
|
||||
and the second algorithm uses two depth-first searches
|
||||
to calculate the diameter.
|
||||
|
||||
\subsubsection{Algoritmi 1}
|
||||
\subsubsection{Algorithm 1}
|
||||
|
||||
Algoritmin alussa
|
||||
yksi solmuista valitaan puun juureksi.
|
||||
Tämän jälkeen algoritmi laskee
|
||||
jokaiseen solmuun,
|
||||
kuinka pitkä on pisin polku,
|
||||
joka alkaa jostakin lehdestä,
|
||||
nousee kyseiseen solmuun asti
|
||||
ja laskeutuu toiseen lehteen.
|
||||
Pisin tällainen polku vastaa puun läpimittaa.
|
||||
First, one of the nodes is chosen to be the root.
|
||||
After this, the algorithm calculates for each node
|
||||
the length of the longest path that begins at some leaf,
|
||||
ascends to the node and then descends to another leaf.
|
||||
The length of the
|
||||
longest such path equals the diameter of the tree.
|
||||
|
||||
Esimerkissä pisin polku alkaa lehdestä 7,
|
||||
nousee solmuun 1 asti ja laskeutuu
|
||||
sitten alas lehteen 6:
|
||||
In the example case, the longest path begins at node 7,
|
||||
ascends to node 1, and then descends to node 6:
|
||||
\begin{center}
|
||||
\begin{tikzpicture}[scale=0.9]
|
||||
\node[draw, circle] (1) at (0,3) {$1$};
|
||||
|
@ -227,32 +221,32 @@ sitten alas lehteen 6:
|
|||
\end{tikzpicture}
|
||||
\end{center}
|
||||
|
||||
Algoritmi laskee ensin dynaamisella ohjelmoinnilla
|
||||
jokaiselle solmulle, kuinka pitkä on pisin polku,
|
||||
joka lähtee solmusta alaspäin.
|
||||
Esimerkiksi yllä olevassa puussa pisin polku
|
||||
solmusta 1 alaspäin on pituudeltaan 2
|
||||
(vaihtoehdot $1 \rightarrow 4 \rightarrow 3$,
|
||||
$1 \rightarrow 4 \rightarrow 7$ ja $1 \rightarrow 2 \rightarrow 6$).
|
||||
The algorithm first calculates using dynamic programming
|
||||
for each node the length of the longest path
|
||||
that goes downwards from the node.
|
||||
For example, in the above tree,
|
||||
the longest path from node 1 downwards has length 2
|
||||
(the path can be $1 \rightarrow 4 \rightarrow 3$,
|
||||
$1 \rightarrow 4 \rightarrow 7$ or $1 \rightarrow 2 \rightarrow 6$).
|
||||
|
||||
Tämän jälkeen algoritmi laskee kullekin solmulle,
|
||||
kuinka pitkä on pisin polku, jossa solmu on käännekohtana.
|
||||
Pisin tällainen polku syntyy valitsemalla kaksi lasta,
|
||||
joista lähtee alaspäin mahdollisimman pitkä polku.
|
||||
Esimerkiksi yllä olevassa puussa solmun 1 lapsista valitaan solmut 2 ja 4.
|
||||
After this, the algorithm calculates for each node
|
||||
the length of the longest path where the node
|
||||
is the turning point of the path.
|
||||
The longest such path can be found by selecting
|
||||
two children with longest paths downwards.
|
||||
For example, in the above graph,
|
||||
nodes 2 and 4 are chosen for node 1.
|
||||
|
||||
\subsubsection{Algoritmi 2}
|
||||
\subsubsection{Algorithm 2}
|
||||
|
||||
Toinen tehokas tapa laskea puun läpimitta
|
||||
perustuu kahteen syvyyshakuun.
|
||||
Ensin valitaan mikä tahansa solmu $a$ puusta
|
||||
ja etsitään siitä kaukaisin solmu $b$
|
||||
syvyyshaulla.
|
||||
Tämän jälkeen etsitään $b$:stä kaukaisin
|
||||
solmu $c$ syvyyshaulla.
|
||||
Puun läpimitta on etäisyys $b$:n ja $c$:n välillä.
|
||||
Another efficient way to calculate the diameter
|
||||
of a tree is based on two depth-first searches.
|
||||
First, we choose an arbitrary node $a$ in the tree
|
||||
and find a node $b$ with maximum distance to $a$.
|
||||
Then, we find a node $c$ with maximum distance to $b$.
|
||||
The diameter is the distance between nodes $b$ and $c$.
|
||||
|
||||
Esimerkissä $a$, $b$ ja $c$ voisivat olla:
|
||||
In the example case, $a$, $b$ and $c$ could be:
|
||||
\begin{center}
|
||||
\begin{tikzpicture}[scale=0.9]
|
||||
\node[draw, circle] (1) at (0,3) {$1$};
|
||||
|
@ -279,12 +273,12 @@ Esimerkissä $a$, $b$ ja $c$ voisivat olla:
|
|||
\end{tikzpicture}
|
||||
\end{center}
|
||||
|
||||
Menetelmä on tyylikäs, mutta miksi se toimii?
|
||||
This is an elegant method, but why does it work?
|
||||
|
||||
Tässä auttaa tarkastella puuta niin,
|
||||
että puun läpimittaa vastaava polku on
|
||||
levitetty vaakatasoon ja muut puun osat
|
||||
riippuvat siitä alaspäin:
|
||||
It helps to draw the tree differently so that
|
||||
the path that corresponds to the diameter
|
||||
is horizontal, and all other
|
||||
nodes hang from it:
|
||||
\begin{center}
|
||||
\begin{tikzpicture}[scale=0.9]
|
||||
\node[draw, circle] (1) at (2,1) {$1$};
|
||||
|
@ -312,29 +306,25 @@ riippuvat siitä alaspäin:
|
|||
\end{tikzpicture}
|
||||
\end{center}
|
||||
|
||||
Solmu $x$ on kohta,
|
||||
jossa polku solmusta $a$ liittyy
|
||||
läpimittaa vastaavaan polkuun.
|
||||
Kaukaisin solmu $a$:sta
|
||||
on solmu $b$, solmu $c$
|
||||
tai jokin muu solmu, joka
|
||||
on ainakin yhtä kaukana solmusta $x$.
|
||||
Niinpä tämä solmu on aina sopiva
|
||||
valinta läpimittaa vastaavan polun
|
||||
toiseksi päätesolmuksi.
|
||||
Node $x$ indicates the place where the path
|
||||
from node $a$ joins the path that corresponds
|
||||
to the diameter.
|
||||
The farthest node from $a$
|
||||
is node $b$, node $c$ or some other node
|
||||
that is at least as far from node $x$.
|
||||
Thus, this node can always be chosen for
|
||||
a starting node of a path that corresponds to the diameter.
|
||||
|
||||
\section{Solmujen etäisyydet}
|
||||
\section{Distances between nodes}
|
||||
|
||||
Vaikeampi tehtävä on laskea
|
||||
jokaiselle puun solmulle
|
||||
jokaiseen suuntaan, mikä on suurin
|
||||
etäisyys johonkin kyseisessä suunnassa
|
||||
olevaan solmuun.
|
||||
Osoittautuu, että tämäkin tehtävä ratkeaa
|
||||
ajassa $O(n)$ dynaamisella ohjelmoinnilla.
|
||||
A more difficult problem is to calculate
|
||||
for each node in the tree and for each direction,
|
||||
the maximum distance to a node in that direction.
|
||||
It turns out that this can be calculated in
|
||||
$O(n)$ time as well using dynamic programming.
|
||||
|
||||
\begin{samepage}
|
||||
Esimerkkipuussa etäisyydet ovat:
|
||||
In the example case, the distances are as follows:
|
||||
\begin{center}
|
||||
\begin{tikzpicture}[scale=0.9]
|
||||
\node[draw, circle] (1) at (0,3) {$1$};
|
||||
|
@ -365,16 +355,16 @@ Esimerkkipuussa etäisyydet ovat:
|
|||
\end{tikzpicture}
|
||||
\end{center}
|
||||
\end{samepage}
|
||||
Esimerkiksi solmussa 4
|
||||
kaukaisin solmu ylöspäin mentäessä
|
||||
on solmu 6, johon etäisyys on 3 käyttäen
|
||||
polkua $4 \rightarrow 1 \rightarrow 2 \rightarrow 6$.
|
||||
For example, the furthest node from node 4
|
||||
upwards is node 6, and the distance to this
|
||||
node is 3 using the path
|
||||
$4 \rightarrow 1 \rightarrow 2 \rightarrow 6$.
|
||||
|
||||
\begin{samepage}
|
||||
Tässäkin tehtävässä hyvä lähtökohta on
|
||||
valita jokin solmu puun juureksi,
|
||||
jolloin kaikki etäisyydet alaspäin
|
||||
saa laskettua dynaamisella ohjelmoinnilla:
|
||||
Also in this problem, a good starting point
|
||||
is to root the tree.
|
||||
After this, all distances downwards can
|
||||
be calculated using dynamic programming:
|
||||
\begin{center}
|
||||
\begin{tikzpicture}[scale=0.9]
|
||||
\node[draw, circle] (1) at (0,3) {$1$};
|
||||
|
@ -403,16 +393,14 @@ saa laskettua dynaamisella ohjelmoinnilla:
|
|||
\end{center}
|
||||
\end{samepage}
|
||||
|
||||
Jäljelle jäävä tehtävä on laskea etäisyydet ylöspäin.
|
||||
Tämä onnistuu tekemällä puuhun toinen läpikäynti,
|
||||
joka pitää mukana tietoa,
|
||||
mikä on suurin etäisyys solmun vanhemmasta
|
||||
johonkin toisessa suunnassa olevaan solmuun.
|
||||
The remaining task is to calculate the distances upwards.
|
||||
This can be done by going through the nodes once again
|
||||
and keeping track of the largest distance from the parent
|
||||
of the current node to some other node in another direction.
|
||||
|
||||
Esimerkiksi solmun 2
|
||||
suurin etäisyys ylöspäin on yhtä suurempi
|
||||
kuin solmun 1 suurin etäisyys
|
||||
johonkin muuhun suuntaan kuin solmuun 2:
|
||||
For example, the distance from node 2 upwards
|
||||
is one larger than the distance from node 1
|
||||
downwards in some other direction than node 2:
|
||||
\begin{center}
|
||||
\begin{tikzpicture}[scale=0.9]
|
||||
\node[draw, circle] (1) at (0,3) {$1$};
|
||||
|
@ -435,8 +423,8 @@ johonkin muuhun suuntaan kuin solmuun 2:
|
|||
|
||||
\end{tikzpicture}
|
||||
\end{center}
|
||||
Lopputuloksena on etäisyydet kaikista solmuista
|
||||
kaikkiin suuntiin:
|
||||
Finally, we can calculate the distances for all nodes
|
||||
and all directions:
|
||||
\begin{center}
|
||||
\begin{tikzpicture}[scale=0.9]
|
||||
\node[draw, circle] (1) at (0,3) {$1$};
|
||||
|
@ -471,23 +459,20 @@ kaikkiin suuntiin:
|
|||
\node[color=red] at (0.2,1.6) {$3$};
|
||||
\end{tikzpicture}
|
||||
\end{center}
|
||||
%
|
||||
% Kummankin läpikäynnin aikavaativuus on $O(n)$,
|
||||
% joten algoritmin kokonais\-aikavaativuus on $O(n)$.
|
||||
|
||||
\section{Binääripuut}
|
||||
\section{Binary trees}
|
||||
|
||||
\index{binxxripuu@binääripuu}
|
||||
\index{binary tree}
|
||||
|
||||
\begin{samepage}
|
||||
\key{Binääripuu} on juurellinen puu,
|
||||
jonka jokaisella solmulla on vasen ja oikea alipuu.
|
||||
On mahdollista, että alipuu on tyhjä,
|
||||
jolloin puu ei jatku siitä pidemmälle alaspäin.
|
||||
Binääripuun jokaisella solmulla on 0, 1 tai 2 lasta.
|
||||
|
||||
Esimerkiksi seuraava puu on binääripuu:
|
||||
A \key{binary tree} is a rooted tree
|
||||
where each node has a left subtree
|
||||
and a right subtree.
|
||||
It is possible that a subtree of a node is empty.
|
||||
Thus, every node in a binary tree has
|
||||
0, 1 or 2 children.
|
||||
|
||||
For example, the following tree is a binary tree:
|
||||
\begin{center}
|
||||
\begin{tikzpicture}[scale=0.9]
|
||||
\node[draw, circle] (1) at (0,0) {$1$};
|
||||
|
@ -508,37 +493,42 @@ Esimerkiksi seuraava puu on binääripuu:
|
|||
\end{center}
|
||||
\end{samepage}
|
||||
|
||||
Binääripuun solmuilla on kolme luontevaa järjestystä,
|
||||
jotka syntyvät rekursiivisesta läpikäynnistä:
|
||||
\index{pre-order}
|
||||
\index{in-order}
|
||||
\index{post-order}
|
||||
|
||||
\index{esijxrjestys@esijärjestys}
|
||||
\index{sisxjxrjestys@sisäjärjestys}
|
||||
\index{jxlkijxrjestys@jälkijärjestys}
|
||||
The nodes in a binary tree have three natural
|
||||
orders that correspond to different ways to
|
||||
recursively traverse the nodes:
|
||||
|
||||
\begin{itemize}
|
||||
\item \key{esijärjestys}: juuri, vasen alipuu, oikea alipuu
|
||||
\item \key{sisäjärjestys}: vasen alipuu, juuri, oikea alipuu
|
||||
\item \key{jälkijärjestys}: vasen alipuu, oikea alipuu, juuri
|
||||
\item \key{pre-order}: first process the root,
|
||||
then traverse the left subtree, then traverse the right subtree
|
||||
\item \key{in-order}: first traverse the left subtree,
|
||||
then process the root, then traverse the right subtree
|
||||
\item \key{post-order}: first traverse the left subtree,
|
||||
then traverse the right subtree, then process the root
|
||||
\end{itemize}
|
||||
|
||||
Esimerkissä kuvatun puun esijärjestys on
|
||||
For the above tree, the nodes in
|
||||
pre-order are
|
||||
$[1,2,4,5,6,3,7]$,
|
||||
sisäjärjestys on $[4,2,6,5,1,3,7]$
|
||||
ja jälkijärjestys on $[4,6,5,2,7,3,1]$.
|
||||
in in-order $[4,2,6,5,1,3,7]$
|
||||
and in post-order $[4,6,5,2,7,3,1]$.
|
||||
|
||||
Osoittautuu, että tietämällä puun esijärjestyksen
|
||||
ja sisäjärjestyksen voi päätellä puun koko rakenteen.
|
||||
Esimerkiksi yllä oleva puu on ainoa mahdollinen
|
||||
puu, jossa esijärjestys on
|
||||
$[1,2,4,5,6,3,7]$ ja sisäjärjestys on $[4,2,6,5,1,3,7]$.
|
||||
Vastaavasti myös jälkijärjestys ja sisäjärjestys
|
||||
määrittävät puun rakenteen.
|
||||
If we know the pre-order and the in-order
|
||||
of a tree, we can find out the exact structure of the tree.
|
||||
For example, the tree above 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]$.
|
||||
Correspondingly, the post-order and the in-order
|
||||
also determine the structure of a tree.
|
||||
|
||||
Tilanne on toinen, jos tiedossa on vain
|
||||
esijärjestys ja jälkijärjestys.
|
||||
Nämä järjestykset eivät
|
||||
kuvaa välttämättä puuta yksikäsitteisesti.
|
||||
Esimerkiksi molemmissa puissa
|
||||
However, the situation is different if we only know
|
||||
the pre-order and the post-order of a tree.
|
||||
In this case, there may be more than one tree
|
||||
that match the orders.
|
||||
For example, in both of the trees
|
||||
\begin{center}
|
||||
\begin{tikzpicture}[scale=0.9]
|
||||
\node[draw, circle] (1) at (0,0) {$1$};
|
||||
|
@ -550,6 +540,6 @@ Esimerkiksi molemmissa puissa
|
|||
\path[draw,thick,-] (1b) -- (2b);
|
||||
\end{tikzpicture}
|
||||
\end{center}
|
||||
esijärjestys on $(1,2)$ ja jälkijärjestys on $(2,1)$,
|
||||
mutta siitä huolimatta puiden rakenteet eivät ole samat.
|
||||
the pre-order is $[1,2]$ and the post-order is $[2,1]$
|
||||
but the trees have different structures.
|
||||
|
||||
|
|
Loading…
Reference in New Issue