\documentclass[11pt]{article}

\usepackage{graphics,epsfig}
\usepackage{fullpage}

\begin{document}

\title{{\bf Heaps. Heapsort.}\\
\normalsize{(CLRS 6)}}
\date{}

\maketitle

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Introduction}

So far we have discussed tools necessary for analysis of algorithms
(growth, summations and recurrences) and we have seen a couple of
sorting algorithms as case-studies.

Today we discuss a data structure called \emph{priority queue}, and
its implementation with a heap.  The heap will lead us to a different
algorithm for sorting, called \emph{heapsort}.

\section{Priority Queue}

\begin{itemize}
\item A priority queue supports the following operations on a set $S$ of
  $n$ elements:
  \begin{itemize}
  \item {\sc Insert}: Insert a new element $e$ in $S$
  \item {\sc FindMin}: Return the minimal element in $S$
  \item {\sc DeleteMin}: Delete the minimal element in $S$
  \end{itemize}
\item Sometimes we are also interested in supporting the following
  operations:
  \begin{itemize}
  \item {\sc Change}: Change the key (priority) of an element in $S$
  \item {\sc Delete}: Delete an element from $S$
  \end{itemize}

\item Priority queues have many applications, e.g. in discrete event
  simulation, graph algorithms

\item We can obviously sort using a priority queue:
  \begin{itemize}
  \item Insert all elements using {\sc Insert}
  \item Delete all elements in order using {\sc FindMin} and {\sc
      DeleteMin}
  \end{itemize}

\end{itemize}


\section{Priority Queue implementations}

\subsection{A Priority Queue with an Array or List}
\begin{itemize}
\item The first implementation that comes to mind is ordered array: \\ 

\includegraphics[height=0.5cm]{Ordered_array.pdf}

\begin{itemize}
\item {\sc FindMin} can be performed in $O(1)$ time
\item {\sc DeleteMin} and {\sc Insert} takes $O(n)$ time since we
  need to expand/compress the array after inserting or deleting element.
\end{itemize}
\item If the array is unordered all operations take $O(n)$ time.
\item We could use double linked sorted list instead of array to avoid the
  $O(n)$ expansion/compression cost
  \begin{itemize}
  \item but {\sc Insert} can still take $O(n)$ time.
  \end{itemize}
\end{itemize}


\subsection{A Priority Queue with a Heap}

\begin{itemize}
\item The common way of implementing a priority queue is using a heap

\item Heap definition:
  
  \fbox{\parbox{11.5cm}{
      \begin{itemize}
      \item Perfectly balanced binary tree
        \begin{itemize}
        \item lowest level can be incomplete (but filled from left-to-right)
        \end{itemize} 
      \item For all nodes $v$ we have key($v$)$\geq$key(parent($v$))
      \end{itemize}
    }}
  
\item Note: this is a \emph{min-heap}; a symmetrical definition is
  possible, giving a \emph{max-heap}.

\item Example:
  
  \vspace{.5\baselineskip}
  
  \includegraphics[height=3cm]{heap.pdf}
  
\item The beauty of heaps is that although they are trees, they can be
  implemented as arrays. The elements in the heap are stored
  level-by-level, left-to-right in the array.
    
  Example:
  
  \vspace{.5\baselineskip}
  
  \includegraphics[height=3cm]{arrayheap.pdf}
  
  \begin{itemize}
  \item the left and right children of node in entry $i$
    are in entry $2i$ and $2i+1$, respectively
  \item the parent of node in entry $i$ is in entry
    $\lfloor \frac{i}{2} \rfloor$
  \end{itemize}
  

\item Properties of heap:
  \begin{itemize}
  \item Height $\Theta(\log n)$ 
  \item For a min-heap: Minimum of $S$ is stored in root (for a
    max-heap, the maximum element is stored in the root).
  \end{itemize}


\item Operations:
  \begin{itemize}
  \item  {\sc Insert}
    \begin{itemize}
    \item Insert element in new leaf in leftmost possible
      position on lowest level
    \item Repeatedly swap element with element in parent node
          until heap order is reestablished (this is refered to as {\sc up-heapify}.
          
          Example: Insertion of 4
          
          \includegraphics[height=3cm]{insert4.pdf}
        \end{itemize}
      \item {\sc FindMin}
        \begin{itemize}
        \item Return root element
        \end{itemize}
        
      \item {\sc DeleteMin}
                \begin{itemize}
                \item Delete element in root
                \item Move element from rightmost leaf on lowest level to
                the root (and delete leaf)
              \item Repeatedly swap element with the smaller of the
                children elements until heap order is reestablished
                (this is refered to as {\sc down-heapify} or sometimes
                just {\sc Heapify}).

                \vspace{.5\baselineskip}

                Example: 

                \includegraphics[height=3cm]{deletemin.pdf}
                \end{itemize}

\item By default {\sc Heapify} works on the root node ($i=1$).  {\sc
    Heapify}(i) means it's called on node $i$ in the heap.  Prior to
  this call, the left and right children of node $i$ must be
  heaps. After {\sc Heapify} (i) is complete, the tree rooted at node
  $i$ is a heap.

        	
\item Changing the priority of a given node or deleting a given node
  can be handled similarly in $O(\log n)$ time.
\begin{itemize}
\item Note: We can delete or update nodes in a heap if we are given
  their index in the array. For e.g. we cannot say ``delete the node
  with priority 37'' because we cannot search (efficiently) in a heap!
  But we can say ``delete the node at index 5''.
\end{itemize}
\end{itemize}



\item {\bf Running time:} All operations traverse at most one
root-leaf path $\Rightarrow O(\log n)$ time.

\end{itemize}



\subsection{Heapsort} 
\begin{itemize} 
\item Sorting using heap takes $\Theta(n\log n)$ time.
  \begin{itemize}
  \item $n\cdot O(\log n)$ time to insert all elements (build the
    heap)
  \item $n\cdot O(\log n)$ time to output sorted elements
  \end{itemize}
  
\item This is not in place.  An in-place sorting algorithm with a heap
  is possible, and is reffered to as \emph{heapsort}. 
  \begin{itemize}
  \item  Build a max-heap 
  \item Repeatedly, delete the largest element, and put it at the end
    of the array.
  \end{itemize} 
\end{itemize} 


\subsection{Building a heap in $O(n)$ time} 

\begin{itemize} 
\item Sometimes we would like to build a heap faster than $O(n\log n)$
\item By default {\sc Heapify} works on the root node ($i=1$).  {\sc
    Heapify}(i) means it's called on node $i$ in the heap.  Prior to
  this call, the left and right children of node $i$ must be
  heaps. After {\sc Heapify} (i) is complete, the tree rooted at node
  $i$ is a heap.

  \begin{itemize}
  \item BUILDHEAP (A)
    \begin{itemize}
    \item {\sc down-heapify} all nodes level-by-level, bottom-up
      (starting at node $n/2$)
    \end{itemize}
    
  \item Correctness: 
    \begin{itemize}
    \item Induction on height of tree: When doing level $i$, all trees
      rooted at level $i-1$ are heaps. 
    \end{itemize}
    
  \item Analysis:
    \begin{itemize}
    \item  The leaves are at height $0$, the root is at height $\log n$    
    \item Cost of {\sc down-heapify} on a node at height $h$ is $h$   
    \item $n$ elements $\Rightarrow \leq \lceil \frac{n}{2}\rceil$
      leaves, ...., $ \lceil \frac{n}{2^h}\rceil$ elements at height 
      $h$
      
    \item Total cost: $\sum_{i=1}^{\log n} h\cdot \lceil
      \frac{n}{2^h}\rceil=\Theta(n)\cdot \sum_{i=1}^{\log n}
      \frac{h}{2^h}$
    \item It can be shown that $\sum_{i=1}^{\log n} \frac{h}{2^h}=O(1)$
      $\Longrightarrow$ the total buildheap cost is $\Theta(n)$
      
    %   \vspace{\baselineskip}
%     \item Computing $\sum_{i=1}^{n} \frac{h}{2^h}$ and
%       $\sum_{i=1}^{\infty} \frac{h}{2^h}$
%       \begin{itemize}
%       \item Differentiate $\sum_{h=0}^{n} x^h = \frac{1 -
%           x^{n+1}}{1-x}$, respectively $\sum_{h=0}^{\infty} x^h =
%         \frac{1}{1-x}$ (assuming $|x|<1$)
%       \item $\sum_{h=0}^{\infty} hx^{h-1}=\frac{1}{(x-1)^2} \Rightarrow
%         \sum_{h=0}^{n} hx^h=\frac{x}{(x-1)^2} \Rightarrow \sum_{h=0}^{n}
%         \frac{h}{2^h}=\frac{1/2}{(1/2-1)^2}=O(1)$
%       \end{itemize}
    \end{itemize}
  \end{itemize}
  
\end{itemize}
\end{document}

