\documentclass[10pt]{article}
\usepackage{fullpage}
\usepackage{graphics,epsfig}
\usepackage{clrscode3e}

\begin{document}

\title{{\bf Sorting in linear time}\\
\normalsize{(CLRS 8.2, 8.3)}}

\date{}

\maketitle

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

We know that it is not possible to sort $n$ elements faster than
$\Omega( n \lg n)$ in the worst case {\bf when using only comparisons}
(i.e. in the comparison-model). The question is: Are there other kinds
of sorting? What else could we use besides comparisons? 

\vspace{ \baselineskip} 
Exercise: Give an $O(n)$ algorithm to sort $n$ integers in the range
$0..999$.

\vspace{ \baselineskip}  

As we can see from this simpleexample, faster sorting algorithm exist,
but they require special assumptions about the input. The most common
ones are bucket sort, counting sort and radix sort, which we discuss below.


\section*{Bucket sort}

Input: integers in the range $\{0,..,N-1\}$, for some $N \ge 2$. 

\fbox{
\parbox{8cm}{

\begin{codebox}
  \Procname{  $\proc{Bucket-Sort}(A)$}
  \li Create an array $B[0..N-1]$
  \li    For $i \gets 0$ \To $n-1$    \Do 
  \li  insert $A[i]$ into $B[A[i]]$ (at end) 
 \li    For $i \gets 0$ \To $N-1$    \Do 
  \li  traverse $B[i]$
  \End
\end{codebox}

}}

\vspace{ \baselineskip} 
Analysis:  $O(n + N)$ time and $O(N+n)$ extra space. 


How does $\Theta(n+N)$ compare with $\Theta ( n \lg n)$? Put
differently, when is Bucket-sort efficient?  
\begin{itemize} 
\item When $N$ is small. For e.g. if $N = O(n)$, then Bucket-sort runs in $O(n)$ time. 
\end{itemize}



\section*{Counting sort}

Input: integers in the range $\{0,..,N-1\}$, for some $N \ge 2$. 

Counting-sort uses the same idea as bucket sort, except that, instead
of creating buckets (with linked lists), it stores everything in an
array. It's more elegant. 

\fbox{
\parbox{8cm}{

\begin{codebox}
  \Procname{  $\proc{Counting-Sort}(A)$}
  \li  Create an auxiliary array $C[0..N-1]$ 
  \li  For $i \gets 0$ \To $N-1$    \Do 
  \li       C[i] = 0
  \End 
  \li  For $i \gets 0$ \To $n-1$    \Do 
  \li      $C[A[i]]++$
  \End 
  \li  For $i \gets 1$ \To $N-1$    \Do 
  \li      C[i] = C[i] + C[i-1]
  \End 
  \li  For  $i = n-1$ down to 0 \Do
  \li      B[C[A[i]]] = A[i]
  \li     C[A[i]]--
  \End
\end{codebox}

}}


\vspace{ \baselineskip} 
Analysis:  $O(n + N)$ time and $O(N+n)$ extra space. 

Counting-sort is stable.
 
\vspace{ \baselineskip} 
\fbox{
  \parbox{15cm} { A sorting algorithm is called \emph{stable} if it
    leaves equal elements in the same order that it found them.  }
}
\vspace{ \baselineskip} 

To understand why stability is important, assume you want to sort a
bunch of names by Last name.  Let's say they were previously sorted by
first name.  If we use a stable sorting algorithm to sort by Last
name, it would keep all the people with same last name in the order
they were in the input, which means that people with same last name
would appear in the order of their first names.




\section*{Radix sort}

To be continued. 



        
\end{document}
