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

📄 sort.cc

📁 早期freebsd实现
💻 CC
字号:
#include <stdio.h>#include <ctype.h>#include <std.h>/* the next 6 #defines implement a very fast in-line stack abstraction       */#define MAX_STACK_SIZE 32#define DISPOSE_STACK(S) (free(S))#define PUSH(LOW,HIGH) do {top->lo = LOW;top++->hi = HIGH;} while (0)#define POP(LOW,HIGH)  do {LOW = (--top)->lo;HIGH = top->hi;} while (0)#define STACK_NOT_EMPTY (stack < top)                #define SWAP(A,B) do {char *_temp = (A);(A) = (B);(B) = _temp;} while (0)/* Discontinue quicksort algorithm when partition gets below this size.   This particular magic number was chosen to work best on a Sun 4/260. */#define MAX_THRESH 30/* Data structure for stack of unfulfilled obligations. */typedef struct {  char **lo;  char **hi;} stack_node;/* Once main array is partially sorted by quicksort the remainder is    completely sorted using insertion sort, since this is efficient    for partitions below MAX_THRESH size. BASE points to the beginning    of the array to sort, and END_PTR points at the very last element in   the array (*not* one beyond it!). */inline static voidinsert_sort (char **base_ptr, char **end_ptr){  char **run_ptr;  char **tmp_ptr = base_ptr;  char **thresh  = end_ptr <? base_ptr + MAX_THRESH;  /* Find the smallest element in the first threshold and put it at the      end of the array.  This is guaranteed to be the smallest element in      the array, and it speeds up the inner loop of insertion sort. */  for (run_ptr = tmp_ptr + 1; run_ptr <= thresh; run_ptr++)    if (strcmp (*run_ptr, *tmp_ptr) < 0)      tmp_ptr = run_ptr;  SWAP (*tmp_ptr, *base_ptr);  /* Typical insertion sort, but we run from the `right-hand-side'     downto the `left-hand-side.' */  for (run_ptr = base_ptr + 1; run_ptr < end_ptr; run_ptr++)    {      char *temp = *(tmp_ptr = run_ptr + 1);      /* Select the correct location for the new element,          by sliding everyone down by 1 to make room! */      while (strcmp (temp, *--tmp_ptr) < 0)        tmp_ptr[1] = *tmp_ptr;      tmp_ptr[1] = temp;     }}/* Return the median value selected from among the    LOW, MIDDLE, and HIGH.  Rearrange LOW and HIGH so   the three values are sorted amongst themselves.    This speeds up later work... */inline static char *find_pivot (char **low, char **high){  char **middle = low + ((high - low ) >> 1);  if (strcmp (*middle, *low) < 0)    SWAP (*middle, *low);  if (strcmp (*high, *middle) < 0)    SWAP (*middle, *high);  else     return *middle;  if (strcmp (*middle, *low) < 0)    SWAP (*middle, *low);  return *middle;}/* Order elements using quicksort.  This implementation incorporates   4 optimizations discussed in Sedgewick:      1. Non-recursive, using an explicit stack of log (n) pointers that       indicate the next array partition to sort.   2. Choses the pivot element to be the median-of-three, reducing      the probability of selecting a bad pivot value.   3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving      insertion sort to sort within the partitions.  This is a      big win, since insertion sort is faster for small, mostly      sorted array segements.      4. The larger of the 2 sub-partitions are always pushed onto the      stack first, with the algorithm then concentrating on the      smaller partition.  This *guarantees* no more than log (n)      stack size is needed! */      voidsort (char **base_ptr, int total_elems){  if (total_elems > MAX_THRESH)    {      char       **lo = base_ptr;      char       **hi = lo + (total_elems - 1);      char       **left_ptr;      char       **right_ptr;      stack_node   stack[MAX_STACK_SIZE];      stack_node  *top = stack + 1;      while (STACK_NOT_EMPTY)        {          /* Select the median-of-three here. This allows us to            skip forward for the LEFT_PTR and RIGHT_PTR. */          char *pivot = find_pivot (lo, hi);          left_ptr  = lo + 1;          right_ptr = hi - 1;           /* Here's the famous ``collapse the walls'' section of            quicksort.  Gotta like those tight inner loops! */          do             {              while (strcmp (*left_ptr, pivot) < 0)                left_ptr++;              while (strcmp (pivot, *right_ptr) < 0)                right_ptr--;              if (left_ptr < right_ptr)                 {                  SWAP (*left_ptr, *right_ptr);                  left_ptr++;                  right_ptr--;                }              else if (left_ptr == right_ptr)                 {                  left_ptr++;                  right_ptr--;                  break;                }            }           while (left_ptr <= right_ptr);          if ((right_ptr - lo) <= MAX_THRESH)             {              if ((hi - left_ptr) <= MAX_THRESH) /* ignore both small tables */                POP (lo, hi);              else              /* ignore small left table */                lo = left_ptr;            }          else if ((hi - left_ptr) <= MAX_THRESH) /* ignore small right table */            hi = right_ptr;          else if ((right_ptr - lo) > (hi - left_ptr))             {                   /* push larger left table */              PUSH (lo, right_ptr);              lo = left_ptr;            }          else             {                   /* push larger right table */              PUSH (left_ptr, hi);              hi = right_ptr;            }        }    }  insert_sort (base_ptr, base_ptr + (total_elems - 1));}

⌨️ 快捷键说明

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