Improve language
This commit is contained in:
parent
9d61b10876
commit
2697233dcb
|
@ -299,7 +299,7 @@ For example, in the array
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
the inversions are $(6,3)$, $(6,5)$ and $(9,8)$.
|
the inversions are $(6,3)$, $(6,5)$ and $(9,8)$.
|
||||||
The number of inversions tells us
|
The number of inversions indicates
|
||||||
how much work is needed to sort the array.
|
how much work is needed to sort the array.
|
||||||
An array is completely sorted when
|
An array is completely sorted when
|
||||||
there are no inversions.
|
there are no inversions.
|
||||||
|
@ -327,22 +327,22 @@ One such algorithm is \key{merge sort}\footnote{According to \cite{knu983},
|
||||||
merge sort was invented by J. von Neumann in 1945.},
|
merge sort was invented by J. von Neumann in 1945.},
|
||||||
which is based on recursion.
|
which is based on recursion.
|
||||||
|
|
||||||
Merge sort sorts the subarray \texttt{t}$[a,b]$ as follows:
|
Merge sort sorts a subarray \texttt{t}$[a \ldots b]$ as follows:
|
||||||
|
|
||||||
\begin{enumerate}
|
\begin{enumerate}
|
||||||
\item If $a=b$, do not do anything, because the subarray is already sorted.
|
\item If $a=b$, do not do anything, because the subarray is already sorted.
|
||||||
\item Calculate the position of the middle element: $k=\lfloor (a+b)/2 \rfloor$.
|
\item Calculate the position of the middle element: $k=\lfloor (a+b)/2 \rfloor$.
|
||||||
\item Recursively sort the subarray \texttt{t}$[a,k]$.
|
\item Recursively sort the subarray \texttt{t}$[a \ldots k]$.
|
||||||
\item Recursively sort the subarray \texttt{t}$[k+1,b]$.
|
\item Recursively sort the subarray \texttt{t}$[k+1 \ldots b]$.
|
||||||
\item \emph{Merge} the sorted subarrays \texttt{t}$[a,k]$ and \texttt{t}$[k+1,b]$
|
\item \emph{Merge} the sorted subarrays \texttt{t}$[a \ldots k]$ and \texttt{t}$[k+1 \ldots b]$
|
||||||
into a sorted subarray \texttt{t}$[a,b]$.
|
into a sorted subarray \texttt{t}$[a \ldots b]$.
|
||||||
\end{enumerate}
|
\end{enumerate}
|
||||||
|
|
||||||
Merge sort is an efficient algorithm, because it
|
Merge sort is an efficient algorithm, because it
|
||||||
halves the size of the subarray at each step.
|
halves the size of the subarray at each step.
|
||||||
The recursion consists of $O(\log n)$ levels,
|
The recursion consists of $O(\log n)$ levels,
|
||||||
and processing each level takes $O(n)$ time.
|
and processing each level takes $O(n)$ time.
|
||||||
Merging the subarrays \texttt{t}$[a,k]$ and \texttt{t}$[k+1,b]$
|
Merging the subarrays \texttt{t}$[a \ldots k]$ and \texttt{t}$[k+1 \ldots b]$
|
||||||
is possible in linear time, because they are already sorted.
|
is possible in linear time, because they are already sorted.
|
||||||
|
|
||||||
For example, consider sorting the following array:
|
For example, consider sorting the following array:
|
||||||
|
@ -539,7 +539,7 @@ $O(n)$ time assuming that every element in the array
|
||||||
is an integer between $0 \ldots c$ and $c=O(n)$.
|
is an integer between $0 \ldots c$ and $c=O(n)$.
|
||||||
|
|
||||||
The algorithm creates a \emph{bookkeeping} array,
|
The algorithm creates a \emph{bookkeeping} array,
|
||||||
whose indices are elements in the original array.
|
whose indices are elements of the original array.
|
||||||
The algorithm iterates through the original array
|
The algorithm iterates through the original array
|
||||||
and calculates how many times each element
|
and calculates how many times each element
|
||||||
appears in the array.
|
appears in the array.
|
||||||
|
@ -620,7 +620,7 @@ be used as indices in the bookkeeping array.
|
||||||
\index{sort@\texttt{sort}}
|
\index{sort@\texttt{sort}}
|
||||||
|
|
||||||
It is almost never a good idea to use
|
It is almost never a good idea to use
|
||||||
a self-made sorting algorithm
|
a home-made sorting algorithm
|
||||||
in a contest, because there are good
|
in a contest, because there are good
|
||||||
implementations available in programming languages.
|
implementations available in programming languages.
|
||||||
For example, the C++ standard library contains
|
For example, the C++ standard library contains
|
||||||
|
@ -749,19 +749,19 @@ struct P {
|
||||||
It is also possible to give an external
|
It is also possible to give an external
|
||||||
\key{comparison function} to the \texttt{sort} function
|
\key{comparison function} to the \texttt{sort} function
|
||||||
as a callback function.
|
as a callback function.
|
||||||
For example, the following comparison function
|
For example, the following comparison function \texttt{comp}
|
||||||
sorts strings primarily by length and secondarily
|
sorts strings primarily by length and secondarily
|
||||||
by alphabetical order:
|
by alphabetical order:
|
||||||
|
|
||||||
\begin{lstlisting}
|
\begin{lstlisting}
|
||||||
bool cmp(string a, string b) {
|
bool comp(string a, string b) {
|
||||||
if (a.size() != b.size()) return a.size() < b.size();
|
if (a.size() != b.size()) return a.size() < b.size();
|
||||||
return a < b;
|
return a < b;
|
||||||
}
|
}
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
Now a vector of strings can be sorted as follows:
|
Now a vector of strings can be sorted as follows:
|
||||||
\begin{lstlisting}
|
\begin{lstlisting}
|
||||||
sort(v.begin(), v.end(), cmp);
|
sort(v.begin(), v.end(), comp);
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
\section{Binary search}
|
\section{Binary search}
|
||||||
|
@ -770,9 +770,9 @@ sort(v.begin(), v.end(), cmp);
|
||||||
|
|
||||||
A general method for searching for an element
|
A general method for searching for an element
|
||||||
in an array is to use a \texttt{for} loop
|
in an array is to use a \texttt{for} loop
|
||||||
that iterates through the elements in the array.
|
that iterates through the elements of the array.
|
||||||
For example, the following code searches for
|
For example, the following code searches for
|
||||||
an element $x$ in the array \texttt{t}:
|
an element $x$ in an array \texttt{t}:
|
||||||
|
|
||||||
\begin{lstlisting}
|
\begin{lstlisting}
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
|
@ -783,8 +783,8 @@ for (int i = 0; i < n; i++) {
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
The time complexity of this approach is $O(n)$,
|
The time complexity of this approach is $O(n)$,
|
||||||
because in the worst case, it is needed to check
|
because in the worst case, it is necessary to check
|
||||||
all elements in the array.
|
all elements of the array.
|
||||||
If the order of the elements is arbitrary,
|
If the order of the elements is arbitrary,
|
||||||
this is also the best possible approach, because
|
this is also the best possible approach, because
|
||||||
there is no additional information available where
|
there is no additional information available where
|
||||||
|
@ -801,17 +801,19 @@ in $O(\log n)$ time.
|
||||||
|
|
||||||
\subsubsection{Method 1}
|
\subsubsection{Method 1}
|
||||||
|
|
||||||
The traditional way to implement binary search
|
The usual way to implement binary search
|
||||||
resembles looking for a word in a dictionary.
|
resembles looking for a word in a dictionary.
|
||||||
At each step, the search halves the active region in the array,
|
The search maintains an active region in the array,
|
||||||
until the target element is found, or it turns out
|
which initially contains all array elements.
|
||||||
that there is no such element.
|
Then, a number of steps is performed,
|
||||||
|
each of which halves the size of the region.
|
||||||
|
|
||||||
First, the search checks the middle element of the array.
|
At each step, the search checks the middle element
|
||||||
|
of the active region.
|
||||||
If the middle element is the target element,
|
If the middle element is the target element,
|
||||||
the search terminates.
|
the search terminates.
|
||||||
Otherwise, the search recursively continues
|
Otherwise, the search recursively continues
|
||||||
to the left or right half of the array,
|
to the left or right half of the region,
|
||||||
depending on the value of the middle element.
|
depending on the value of the middle element.
|
||||||
|
|
||||||
The above idea can be implemented as follows:
|
The above idea can be implemented as follows:
|
||||||
|
@ -827,17 +829,16 @@ while (a <= b) {
|
||||||
}
|
}
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
The algorithm maintains a range $a \ldots b$
|
In this implementation, the active region is $a \ldots b$,
|
||||||
that corresponds to the active region of the array.
|
and initially the region is $0 \ldots n-1$.
|
||||||
Initially, the range is $0 \ldots n-1$, the whole array.
|
The algorithm halves the size of the region at each step,
|
||||||
The algorithm halves the size of the range at each step,
|
|
||||||
so the time complexity is $O(\log n)$.
|
so the time complexity is $O(\log n)$.
|
||||||
|
|
||||||
\subsubsection{Method 2}
|
\subsubsection{Method 2}
|
||||||
|
|
||||||
An alternative method for implementing binary search
|
An alternative method to implement binary search
|
||||||
is based on an efficient way to iterate through
|
is based on an efficient way to iterate through
|
||||||
the elements in the array.
|
the elements of the array.
|
||||||
The idea is to make jumps and slow the speed
|
The idea is to make jumps and slow the speed
|
||||||
when we get closer to the target element.
|
when we get closer to the target element.
|
||||||
|
|
||||||
|
@ -860,16 +861,13 @@ if (t[k] == x) {
|
||||||
}
|
}
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
The variables $k$ and $b$ contain the position
|
During the search, the variable $b$
|
||||||
in the array and the jump length.
|
contains the current jump length.
|
||||||
If the array contains the element $x$,
|
|
||||||
the position of $x$ will be in the variable $k$
|
|
||||||
after the search.
|
|
||||||
The time complexity of the algorithm is $O(\log n)$,
|
The time complexity of the algorithm is $O(\log n)$,
|
||||||
because the code in the \texttt{while} loop
|
because the code in the \texttt{while} loop
|
||||||
is performed at most twice for each jump length.
|
is performed at most twice for each jump length.
|
||||||
|
|
||||||
\subsubsection{C++ implementation}
|
\subsubsection{C++ functions}
|
||||||
|
|
||||||
The C++ standard library contains the following functions
|
The C++ standard library contains the following functions
|
||||||
that are based on binary search and work in logarithmic time:
|
that are based on binary search and work in logarithmic time:
|
||||||
|
@ -895,7 +893,7 @@ if (k < n && t[k] == x) {
|
||||||
}
|
}
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
The following code counts the number of elements
|
Then, the following code counts the number of elements
|
||||||
whose value is $x$:
|
whose value is $x$:
|
||||||
|
|
||||||
\begin{lstlisting}
|
\begin{lstlisting}
|
||||||
|
|
Loading…
Reference in New Issue