\documentclass[11pt]{article}
\usepackage{latexsym}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsthm}
\usepackage{epsfig}
\usepackage{psfig}
\newcommand{\handout}[5]{
\noindent
\begin{center}
\framebox{
\vbox{
\hbox to 5.78in { {\bf 6.897: Advanced Data Structures } \hfill #2 }
\vspace{4mm}
\hbox to 5.78in { {\Large \hfill #5 \hfill} }
\vspace{2mm}
\hbox to 5.78in { {\em #3 \hfill #4} }
}
}
\end{center}
\vspace*{4mm}
}
\newcommand{\lecture}[4]{\handout{#1}{#2}{#3}{Scribe: #4}{Lecture #1}}
\newtheorem{theorem}{Theorem}
\newtheorem{corollary}[theorem]{Corollary}
\newtheorem{lemma}[theorem]{Lemma}
\newtheorem{observation}[theorem]{Observation}
\newtheorem{proposition}[theorem]{Proposition}
\newtheorem{definition}[theorem]{Definition}
\newtheorem{claim}[theorem]{Claim}
\newtheorem{fact}[theorem]{Fact}
\newtheorem{assumption}[theorem]{Assumption}
% 1-inch margins, from fullpage.sty by H.Partl, Version 2, Dec. 15, 1988.
\topmargin 0pt
\advance \topmargin by -\headheight
\advance \topmargin by -\headsep
\textheight 8.9in
\oddsidemargin 0pt
\evensidemargin \oddsidemargin
\marginparwidth 0.5in
\textwidth 6.5in
\parindent 0in
\parskip 1.5ex
%\renewcommand{\baselinestretch}{1.25}
\begin{document}
\lecture{14 --- March 31, 2005}{Spring 2005}{Prof.\ Erik Demaine}{Jelani Nelson}
\section{Overview}
In the last lecture, we discussed algorithms for integer sorting. In this
lecture we will discuss the relationship between integer sorting algorithms
and priority queue data structures. It is obvious that fast priority
queues imply fast sorting, since if a priority queue can do \textsc{Insert}
and \textsc{Delete-min} in $O(f(n))$, then we can sort in $O(nf(n))$ by
inserting all elements into the queue then calling \textsc{Delete-min} $n$
times. So, we will focus in this lecture on the reverse --- that is, how
to make fast priority queues once we have fast sorting algorithms.
\section{Priority Queue}
A priority queue, also sometimes called a {\em heap}, is a data structure
that performs the following operations:
\begin{itemize}
\item \textsc{Insert}($x,key$) -- Insert the element $x$ into the heap
with key $key$.
\item \textsc{Delete-Min}() -- Return the smallest element in the heap
under key order. Also, delete this element from the heap.
\item \textsc{Decrease-Key}($x,key$) -- Change the key of item $x$ in
the heap to $key$. $key$ must not be greater than $x$'s current key
value.
\item \textsc{Meld}($H_1, H_2$) -- Takes two heaps as input and
produces a new heap that contains all the elements of the two that
are input.
\end{itemize}
The fundamental operations are \textsc{Insert} and
\textsc{Delete-Min}. The other two operations are motivated by
applications to graph algorithms.
Two old but very important algorithms in computer science that require
heaps are Dijkstra's shortest path algorithm in \cite{dijkstra}, and
Prim's algorithm for minimum spanning tree, discussed in \cite{prim}.
Note one difference in the types of priority queues needed in the two
algorithms: in Dijkstra's algorithm the minimum key in the heap never
decreases. We call heaps that only support such situations {\em
monotone}. If we remember the way Dijkstra's algorithms and Prim's
algorithm work, each of them performs $O(m)$ decrease-key operations,
and $O(n)$ \textsc{Insert}'s and \textsc{Delete}'s. This motivates the
need for \textsc{Decrease-Key} being faster than \textsc{Delete-Min}.
Another old algorithm that uses the priority queue is Edmonds'
algorithm for directed MST \cite{edmonds}. This can be implemented
efficiently using meldable priority queues.
\subsection{Results}
For the following results, you can assume that a fast \textsc{Meld} is
not supported unless otherwise stated. In the comparison model, a
normal binary heap can achieve $O(\log n)$ per operation. Fibonacci
heaps, introduced in \cite{fibheap}, achieve $O(1)$
\textsc{Decrease-Key} and \text{Insert} and $O(\log n)$
\textsc{Delete-Min} (all times amortized). Note, this implies an
$O(n\log n+m)$ running time for Prim's and Dijkstra's algorithms. A
worst-case version of the Fibonacci heap, which also achieves $O(1)$
inserts, was shown in \cite{brodal}.
For integer priority queues, the atomic heap was introduced in
\cite{atomic}, which achieves $O(1)$ amortized time per operation for
$O(\hbox{polylog}n)$ elements. From a high-level point of view, the
atomic heap works much like a fusion tree (and thus even supports
predecessor and successor queries). The paper discusses how to use
this heap for an optimal $O(n+m)$ MST algorithm (note that this is not
through direct implementation of any classic algorithm). The only
linear time algorithm for MST known in the comparison model is
randomized, found in \cite{karger}. The best deterministic MST
algorithm, due to \cite{chazelle}, runs in time $O((n+m)\alpha(n))$.
As far as relating sorting to priority queues, it was shown in
\cite{thorup00} that $O(n \cdot S(n,w))$ sorting implies an
$O(S(n,w))$ amortized per operation monotone priority queue. This
result was later improved to worst-case and without the monotonicity
condition in \cite{thorup02}. Work has also been done in showing how
to use a fast priority queue to get a fast meldable priority queue.
It is shown in \cite{meld} that an $O(P(n,w))$ time per operation
priority queue implies an $O(P(n,w)\alpha(n))$ time per operation
meldable priority queue. The $\alpha(n)$ was essentially removed
(disappears for the $P(n,w)$ we currently know and care about) in
\cite{bettermeld}.
The best known priority queue with constant \textsc{Decrease-Key} does
not match the current sorting bound. Rather, it achieves $O(\lg\lg n)$
per \textsc{Delete-Min} \cite{thorup03}. Beside MST, another important
application of such queues was solved through different techniques:
single-source shortest paths were shown to be computable in linear
time, $O(m+n)$, in \cite{thorup99}. However, this is only for the
undirected case, and the directed version still relies of priority
queues with constant \textsc{Decrease-Key}.
The rest of this lecture discusses what appears to be a simpler way to
convert $O(n \cdot S(n,w))$ sorting to priority queues with operations
supported in $O(S(n,w))$ time. This is an ad-hoc creation of your
teachning staff and has not been checked extensively, so it should be
trusted accordingly.
\subsubsection{The Priority Queue}
We will keep $\Theta(\lg n)$ buckets, $B_0,B_1,...$. Each $B_i$ will
either be:
\begin{itemize}
\item \underline{Empty}
\item \underline{Sorted} and of size at most $2^i$, stored in a linked list
(we will charge to pay for the sort).
\item \underline{Semi-structured}:
\begin{itemize}
\item[-] Unstructured part $U_i$ of arbitrary size, stored in a linked
list (we will be able to charge the elements of $U_i$).
\item[-] Structured part $S_i$ split into $\Omega(2^{i/2})$ groups of
size $\Theta(2^{i/2})$ each. Each group is unsorted, but the groups are
in order. In our charging argument, we will charge for the groups
beyond $\Theta(2^{i/2})$.
\end{itemize}
\end{itemize}
We will always keep $B_0$ semi-structured. For semi-structured
buckets $B_i,B_j$, if $i