⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iqsort.h

📁 一个不错的fastdb使用例子
💻 H
字号:
/*
** Sorting stuff by Dann Corbit and Pete Filandr.
** (dcorbit@connx.com and pfilandr@mindspring.com)
** Use it however you like.
*/

//
//  The insertion sort template is used for small partitions.
//  Insertion sort is stable.
//

template < class e_type >
void insertion_sort(e_type * array, size_t nmemb)
{
  e_type temp,
  *last,
  *first,
  *middle;

  if (nmemb > 1)
  {
    first = middle = 1 + array;
    last = nmemb - 1 + array;

    while (first != last)
    {
      ++first;

      if ((*(middle) > *(first)))
      {
        middle = first;
      }
    }

    if ((*(array) > *(middle)))
    {
      ((void) ((temp) = *(array), *(array) = *(middle), *(middle) = (temp)));
    }

    ++array;

    while (array != last)
    {
      first = array++;

      if ((*(first) > *(array)))
      {
        middle = array;
        temp = *middle;

        do
        {
          *middle-- = *first--;
        }
        while ((*(first) > *(&temp)));

        *middle = temp;
      }
    }
  }
}

//
// The median estimate is used to choose pivots for the quicksort algorithm
//

template < class e_type >
void median_estimate(e_type * array, size_t n)
{
  e_type          temp;
  long unsigned   lu_seed = 123456789LU;
  const size_t    k = ((lu_seed) = 69069 * (lu_seed) + 362437) % --n;
  ((void) ((temp) = *(array), *(array) = *(array + k), *(array + k) = (temp)));

  if ((*((array + 1)) > *((array))))
  {
    (temp) = *(array + 1);

    if ((*((array + n)) > *((array))))
    {
      *(array + 1) = *(array);

      if ((*(&(temp)) > *((array + n))))
      {
        *(array) = *(array + n);
        *(array + n) = (temp);
      }
      else
      {
        *(array) = (temp);
      }
    }
    else
    {
      *(array + 1) = *(array + n);
      *(array + n) = (temp);
    }
  }
  else
  {
    if ((*((array)) > *((array + n))))
    {
      if ((*((array + 1)) > *((array + n))))
      {
        (temp) = *(array + 1);
        *(array + 1) = *(array + n);
        *(array + n) = *(array);
        *(array) = (temp);
      }
      else
      {
        ((void) (((temp)) = *((array)), *((array)) = *((array + n)), *((array + n)) = ((temp))));
      }
    }
  }
}


//
// This is the heart of the quick sort algorithm used here.
// If the sort is going quadratic, we switch to heap sort.
// If the partition is small, we switch to insertion sort.
//

template < class e_type >
void qloop(e_type * array, size_t nmemb, size_t d)
{
  e_type temp,
  *first,
  *last;

  while (nmemb > 50)
  {
    if (sorted(array, nmemb))
    {
      return;
    }

    if (!d--)
    {
      heapsort(array, nmemb);
      return;
    }

    median_estimate(array, nmemb);
    first = 1 + array;
    last = nmemb - 1 + array;

    do
    {
      ++first;
    }
    while ((*(array) > *(first)));

    do
    {
      --last;
    }
    while ((*(last) > *(array)));

    while (last > first)
    {
      ((void) ((temp) = *(last), *(last) = *(first), *(first) = (temp)));

      do
      {
        ++first;
      }
      while ((*(array) > *(first)));

      do
      {
        --last;
      }
      while ((*(last) > *(array)));
    }

    ((void) ((temp) = *(array), *(array) = *(last), *(last) = (temp)));
    qloop(last + 1, nmemb - 1 + array - last, d);
    nmemb = last - array;
  }

  insertion_sort(array, nmemb);
}

//
// This heap sort is better than average because it uses Lamont's heap.
//

template < class e_type >
void heapsort(e_type * array, size_t nmemb)
{
  size_t i,
  child,
  parent;
  e_type temp;

  if (nmemb > 1)
  {
    i = --nmemb / 2;

    do
    {
      {
        (parent) = (i);
        (temp) = (array)[(parent)];
        (child) = (parent) * 2;

        while ((nmemb) > (child))
        {
          if ((*((array) + (child) + 1) > *((array) + (child))))
          {
            ++(child);
          }

          if ((*((array) + (child)) > *(&(temp))))
          {
            (array)[(parent)] = (array)[(child)];
            (parent) = (child);
            (child) *= 2;
          }
          else
          {
            --(child);
            break;
          }
        }

        if ((nmemb) == (child) && (*((array) + (child)) > *(&(temp))))
        {
          (array)[(parent)] = (array)[(child)];
          (parent) = (child);
        }

        (array)[(parent)] = (temp);
      }
    }
    while (i--);

    ((void) ((temp) = *(array), *(array) = *(array + nmemb), *(array + nmemb) = (temp)));

    for (--nmemb; nmemb; --nmemb)
    {
      {
        (parent) = (0);
        (temp) = (array)[(parent)];
        (child) = (parent) * 2;

        while ((nmemb) > (child))
        {
          if ((*((array) + (child) + 1) > *((array) + (child))))
          {
            ++(child);
          }

          if ((*((array) + (child)) > *(&(temp))))
          {
            (array)[(parent)] = (array)[(child)];
            (parent) = (child);
            (child) *= 2;
          }
          else
          {
            --(child);
            break;
          }
        }

        if ((nmemb) == (child) && (*((array) + (child)) > *(&(temp))))
        {
          (array)[(parent)] = (array)[(child)];
          (parent) = (child);
        }

        (array)[(parent)] = (temp);
      }

      ((void) ((temp) = *(array), *(array) = *(array + nmemb), *(array + nmemb) = (temp)));
    }
  }
}

//
// We use this to check to see if a partition is already sorted.
//

template < class e_type >
int sorted(e_type * array, size_t nmemb)
{
  for (--nmemb; nmemb; --nmemb)
  {
    if ((*(array) > *(array + 1)))
    {
      return 0;
    }

    ++array;
  }

  return 1;
}

//
// We use this to check to see if a partition is already reverse-sorted.
//

template < class e_type >
int             rev_sorted(e_type * array, size_t nmemb)
{
  for (--nmemb; nmemb; --nmemb)
  {
    if ((*(array + 1) > *(array)))
    {
      return 0;
    }

    ++array;
  }

  return 1;
}

//
// We use this to reverse a reverse-sorted partition.
//

template < class e_type >
void rev_array(e_type * array, size_t nmemb)
{
  e_type          temp,
  *end;

  for (end = array + nmemb - 1; end > array; ++array)
  {
    ((void) ((temp) = *(array), *(array) = *(end), *(end) = (temp)));
    --end;
  }
}

//
// Introspective quick sort algorithm user entry point.
// You do not need to directly call any other sorting template.
// This sort will perform very well under all circumstances.
//

template < class e_type >
void iqsort(e_type * array, size_t nmemb)
{
  size_t d,
  n;

  if (nmemb > 1 && !sorted(array, nmemb))
  {
    if (!rev_sorted(array, nmemb))
    {
      n = nmemb / 4;
      d = 2;

      while (n)
      {
        ++d;
        n /= 2;
      }

      qloop(array, nmemb, 2 * d);
    }
    else
    {
      rev_array(array, nmemb);
    }
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -