index↑
FSU Seal - 1851     CIS 4930 Top 10 Algorithms
Chris Lacher
QuickSort
  index↑

Resources


Basic Algorithm

template <typename T>
size_t Partition2 (T* v, size_t beg, size_t end, size_t& comps)
// C++ implementation of Cormen version
{
  size_t last = end - 1;

  /* // randomized version: choose pivot index at random and swap into last element
  size_t pivotIndex = ran(beg,end);
  T pivot = v[pivotIndex]; 
  v[pivotIndex] = v[last];
  v[last] = pivot;
  // */
  T pivot = v[last];

  size_t p = beg;
  for (size_t j = beg; j != last; ++j)
  {
    if (!(pivot < v[j])) // if (v[j] <= pivot)
    {
      XC(v[p],v[j]);
      ++p;
    }
    ++comps;
  }
  XC (v[p],v[last]);
  return p;
}

template <typename T>
void QuickSort2 (T* v, size_t beg, size_t end, size_t& comps)
{
  if (beg != end && beg != end - 1)
  {
    size_t p = Partition2(v, beg, end, comps);
    QuickSort2(v, beg, p, comps);
    QuickSort2(v, ++p, end, comps);
  }
}

Properties


Variations


Order Statistics


Example Driver Program

/* 
   sort_spy.cpp
*/

#include <iostream>
#include <iomanip>
#include <fstream>
#include <cctype>
#include <cmath>

#include <vector.h>
#include <deque.h>
#include <list.h>
#include <genalg.h>
#include <gheap.h>
#include <gsort.h>
#include <compare.h>
#include <insert.h>
#include <xstring.h>

// column widths in table
const int c1 = 15,
          c2 = 9 ,
          c3 = 9 ,
          c4 = 13,
          c5 = 10,
          c6 = 13;


template < typename T >
void XC (T& x , T& y)
{
  T z = x;
  x = y;
  y = z;
}

template < typename T >
bool CheckSort(T* a, size_t low, size_t hih)
{
  if (low >= hih) return 1;
  if (low == --hih) return 1;
  for ( ; low < hih; ++low)
  {
    if (a[low] > a[low+1])
    {
      std::cerr << "  ** bad sort result detected at index " << low << '\n';  
      return 0;
    }
  }
  // std::cout << "  ** sort OK\n";
  return 1;
}


template < typename T >
size_t Partition00(T* a, size_t low, size_t hih, size_t& comps);

template <typename T>
void QuickSort00 (T* v, size_t beg, size_t end, size_t& comps);

template < typename T >
size_t Partition01(T* a, size_t low, size_t hih, size_t& comps);

template <typename T>
void QuickSort01 (T* v, size_t beg, size_t end, size_t& comps);

template <typename T>
size_t Partition1 (T* v, size_t first, size_t last, size_t& comps);

template <typename T>
void QuickSort1 (T* v, size_t beg, size_t end, size_t& comps);

template <typename T>
size_t Partition2 (T* v, size_t beg, size_t end, size_t& comps);

template <typename T>
void QuickSort2 (T* v, size_t beg, size_t end, size_t& comps);

template <typename T>
void QuickSelect (T* v, size_t beg, size_t end, size_t k, size_t& comps);

template < typename T >
void SelectionSort  (T* array, size_t beg, size_t end, size_t& comps);

template < typename T >
void InsertionSort (T* array, size_t beg, size_t end, size_t& comps);

int main (int argc, char* argv[])
{
  if (argc < 2)
  {
    std::cout << " ** ERROR: Expected input file name - try again **\n";
    return (EXIT_FAILURE);
  }

  std::ifstream ifs (argv[1]);
  fsu::Vector<long> v(0), w(0);
  long num;
  while (ifs >> num)
    v.PushBack(num);
  ifs.close();

  size_t size = v.Size();
  w.SetSize(size);
  long * a = new long [size];
  bool select_check, insert_check, qsort00_check, qsort01_check, qsort1_check, qsort2_check;

  // SelectionSort
  fsu::g_copy (v.Begin(), v.End(), a);
  size_t sscomps = 0;
  std::cout << "SelectionSort running ... " << std::flush;
  SelectionSort(a, 0, size, sscomps);
  select_check = CheckSort(a, 0, size);
  std:: cout << '\n';
  // */

  // InsertionSort
  fsu::g_copy (v.Begin(), v.End(), a);
  size_t iscomps = 0;
  std::cout << "InsertionSort running ... " << std::flush;
  InsertionSort(a, 0, size, iscomps);
  std:: cout << '\n';
  insert_check = CheckSort(a, 0, size);
  // */

  // QuickSort00
  fsu::g_copy (v.Begin(), v.End(), a);
  size_t qs00comps = 0;
  std::cout << "QuickSort00 running ... " << std::flush;
  QuickSort00(a, 0, size, qs00comps);
  std:: cout << '\n';
  qsort00_check = CheckSort(a, 0, size);
  // */

  // QuickSort01
  fsu::g_copy (v.Begin(), v.End(), a);
  size_t qs01comps = 0;
  std::cout << "QuickSort01 running ... " << std::flush;
  QuickSort01(a, 0, size, qs01comps);
  std:: cout << '\n';
  qsort01_check = CheckSort(a, 0, size);
  // */

  // QuickSort1
  fsu::g_copy (v.Begin(), v.End(), a);
  size_t qs1comps = 0;
  std::cout << "QuickSort1 running ... " << std::flush;
  QuickSort1(a, 0, size, qs1comps);
  std:: cout << '\n';
  qsort1_check = CheckSort(a, 0, size);
  // */

  // QuickSort2
  fsu::g_copy (v.Begin(), v.End(), a);
  size_t qs2comps = 0;
  std::cout << "QuickSort2 running ... " << std::flush;
  QuickSort2(a, 0, size, qs2comps);
  std:: cout << '\n';
  qsort2_check = CheckSort(a, 0, size);
  fsu::g_copy (a, a+size, w.Begin());
  // */

  // QuickMedian
  fsu::g_copy (v.Begin(), v.End(), a);
  size_t qmcomps = 0;
  std::cout << "QuickSelect running ... " << std::flush;
  QuickSelect(a, 0, size, size/2, qmcomps);
  std:: cout << '\n';
  // */

  std::ofstream ofs;
  if (argc > 2)
  {
    ofs.open(argv[2]);
    w.Display(ofs, ' ');
    ofs << '\n';
    ofs.close();
  }
  else
  {
    w.Display(std::cout, ' ');
    std::cout << '\n';
  }

  // output comps data
  size_t nlogn = size*(size_t)log2(size);
  size_t nsquared = size*(1+size)/2;

  std::cout 
    << '\n'
    << std::setw(c1) << "sort-alg"  << std::setw(c2) << "check" << std::setw(c3) << "n"  << std::setw(c4)       << "comps"  << std::setw(c5) << "n log n" << std::setw(c6) << "n(n+1)/2" << '\n'
    << std::setw(c1) << "--------"  << std::setw(c2) << "-----" << std::setw(c3) << "----" << std::setw(c4)     << "-----"  << std::setw(c5) << "-------" << std::setw(c6) << "--------" << '\n'
    << std::setw(c1) << "Selection" << std::setw(c2) << select_check << std::setw(c3) << size << std::setw(c4)  << sscomps  << std::setw(c5) << nlogn << std::setw(c6) << nsquared << '\n'
    << std::setw(c1) << "Insertion" << std::setw(c2) << insert_check << std::setw(c3) << size << std::setw(c4)  << iscomps  << std::setw(c5) << nlogn << std::setw(c6) << nsquared << '\n'
    << std::setw(c1) << "Quick00"   << std::setw(c2) << qsort00_check << std::setw(c3) << size << std::setw(c4) << qs00comps << std::setw(c5) << nlogn << std::setw(c6) << nsquared << '\n'
    << std::setw(c1) << "Quick01"   << std::setw(c2) << qsort01_check << std::setw(c3) << size << std::setw(c4) << qs01comps << std::setw(c5) << nlogn << std::setw(c6) << nsquared << '\n'
    << std::setw(c1) << "Quick1"    << std::setw(c2) << qsort1_check << std::setw(c3) << size << std::setw(c4)  << qs1comps << std::setw(c5) << nlogn << std::setw(c6) << nsquared << '\n'
    << std::setw(c1) << "Quick2"    << std::setw(c2) << qsort2_check << std::setw(c3) << size << std::setw(c4)  << qs2comps << std::setw(c5) << nlogn << std::setw(c6) << nsquared << '\n'
    << '\n';

  std::cout 
    << '\n'
    << std::setw(c1) << "med-alg"  << std::setw(c2) << "med-val"  << std::setw(c3) << "n" << std::setw(c4)    << "comps" << std::setw(c5)  << "n log n" << std::setw(c6) << "n(n+1)/2" << '\n'
    << std::setw(c1) << "-------"  << std::setw(c2) << "-------"  << std::setw(c3) << "----" << std::setw(c4) << "-----" << std::setw(c5)  << "-------" << std::setw(c6) << "--------" << '\n'
    << std::setw(c1) << "QSort2"   << std::setw(c2) << w[size/2]  << std::setw(c3) << size << std::setw(c4)   << qs2comps << std::setw(c5) << nlogn     << std::setw(c6) << nsquared << '\n'
    << std::setw(c1) << "QSelect"  << std::setw(c2) << a[size/2]  << std::setw(c3) << size << std::setw(c4)   << qmcomps  << std::setw(c5) << nlogn     << std::setw(c6) << nsquared << '\n'
    << '\n';

  return 0;
}
  index↑