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

📄 gensort.h

📁 b tree how to operate on b tr
💻 H
字号:
/*JS***********************************************************************    File    : GENSORT.H*    Language: ANSI-C*    Author  : Joerg Schoen*    Purpose : To generate automatically code for a sorting routine.**              $Id: gensort.h,v 1.6 1997/12/15 21:44:17 joerg Stab joerg $**  You have to define the following preprocessor symbols:*  GENSORT_NAME       will be the name of the generated routine.*  GENSORT_TYPE       is the type of the array to be sorted.*  GENSORT_KEYTYPE    is the type of the key of the array elements.*  GENSORT_GETKEY(a)  is a macro to get the key element of the array*                     element a.*  GENSORT_COMPAREKEYS(k1,k2) compares the two key elements k1 and k2 with*                     condition "lower than" and yields TRUE / FALSE values.*                     If the two keys match, it must return FALSE!**  With the line*     #include "gensort.h"*  this file will automatically generate a sort routine.**  The generated routine will have the prototype*     void GENSORT_NAME(GENSORT_TYPE *array,long n)*   and sorts the n array entries array[0] to array[n - 1].**  At the end of this file the symbols GENSORT_* are undefined for reuse.**  Flags:*   If the flag "GENSORT_USEPOINTERS" is defined, the routine uses pointer*    gymnastics instead of indices, which is faster on some machines.**   If the flag "GENSORT_NISINT" is defined, the size argument n to the*    generated routine is an integer instead of the default long.**   If the flag "GENSORT_NOSMALL" is defined, the quicksort routines do*    not use a straight insertion algorithm for small n. The threshold*    for n can be changed by defining "GENSORT_LIMIT" as the threshold,*    the default is given below. Straight insertion is not used if the*    macro "GENSORT_SWAP" is defined.**   If the flag "GENSORT_HEAPSORT" is defined, the sort routine uses heap-*    sort instead of the default quicksort algorithm.**   If the symbol "GENSORT_ARGSPROTO" and "GENSORT_ARGS" is defined, the*    function has additional arguments.**   If the symbol "GENSORT_SWAP" is defined, exchange of two elements is*    done with the macro GENSORT_SWAP instead with a temporary variable.*    The macro is called via "GENSORT_SWAP(a,i,j);" enclosed in*    curly brackets and is expected to exchange the elements with index i*    and j in the array a. Usage of "GENSORT_SWAP" together with*    "GENSORT_HEAPSORT" is not possible!**  The quicksort is a recursive routine which uses at most*      log_2(n) * (3 * sizeof(GENSORT_TYPE*) + sizeof(GENSORT_KEYTYPE)*                  sizeof(GENSORT_TYPE))*   bytes of stack (may be smaller if optimizer is good).**  Example 1: To generate a quicksort routine which sorts an integer array*   in increasing order, use the following lines:*      | Left margin*      V*      #define GENSORT_NAME                 intquicksort*      #define GENSORT_TYPE                 int*      #define GENSORT_KEYTYPE              int*      #define GENSORT_GETKEY(a)            a*      #define GENSORT_COMPAREKEYS(k1,k2)   k1 < k2**      #include "gensort.h"**  Example 2: To generate a pointer quicksort routine that sorts a structure*   according to a string in the key field (<string.h> is included to get*   the prototype for the strcmp function):*      | Left margin*      V*      #include <string.h>**      struct Test {*        char *KeyString;*        int   OtherFields;*         ....*      };**      #define GENSORT_NAME                 namequicksort*      #define GENSORT_TYPE                 struct Test*      #define GENSORT_KEYTYPE              char **      #define GENSORT_GETKEY(a)            a.KeyString*      #define GENSORT_COMPAREKEYS(k1,k2)   strcmp(k1,k2) < 0**      #define GENSORT_USEPOINTERS**      #include "gensort.h"**  Example 3: Generate a routine to sort an indirection table 'ind' for*   a string array 'table', i. e. 'table' stays unsorted, but 'table[ind[i]]'*   will access the original array in sorted order*      | Left margin*      V*      #include <string.h>**      ...**      #define GENSORT_NAME                 indquicksort*      #define GENSORT_ARGS                 ,strings*      #define GENSORT_ARGSPROTO            ,char **strings*      #define GENSORT_TYPE                 int*      #define GENSORT_KEYTYPE              char **      #define GENSORT_GETKEY(a)            strings[a]*      #define GENSORT_COMPAREKEYS(k1,k2)   strcmp(k1,k2) < 0**      #define GENSORT_NISINT**      #include "gensort.h"**      ...**      {*        char **strings;*        int i,n,*ind;**        ...**        for(i = 0 ; i < n ; i++) ind[i] = i;**        indquicksort(ind,n,strings);**        for(i = 0 ; i < n ; i++)*          printf("%s\n",strings[ind[i]]);**      }**************************************************************************//*  Check if all symbols we need are defined, so that user gets a *   message from the preprocessor in case he forgot something. */#ifndef GENSORT_NAME# error "gensort.h": Symbol "GENSORT_NAME" undefined!#endif#ifndef GENSORT_TYPE# error "gensort.h": Symbol "GENSORT_TYPE" undefined!#endif#ifndef GENSORT_KEYTYPE# error "gensort.h": Symbol "GENSORT_KEYTYPE" undefined!#endif#ifndef GENSORT_GETKEY# error "gensort.h": Macro "GENSORT_GETKEY"  undefined!#endif#ifndef GENSORT_COMPAREKEYS# error "gensort.h": Macro "GENSORT_COMPAREKEYS"  undefined!#endif#ifndef GENSORT_ARGSPROTO /*  If not given, set them to nothing  */# define GENSORT_ARGSPROTO# define GENSORT_ARGS#endif#ifndef GENSORT_LIMIT/*  If array size is GENSORT_LIMIT or below, use straight insertion  */# define GENSORT_LIMIT   14  /*  value is hand optimized  */#endif#ifndef GENSORT_INTTYPE# ifdef GENSORT_NISINT#  define GENSORT_INTTYPE     int# else#  define GENSORT_INTTYPE     long# endif#endif#ifndef GENSORT_HEAPSORT# ifndef GENSORT_USEPOINTERS/* ******   Quicksort without pointers     *********** */void GENSORT_NAME(GENSORT_TYPE *__array,GENSORT_INTTYPE __n GENSORT_ARGSPROTO){  register GENSORT_INTTYPE __i,__j;  GENSORT_KEYTYPE __x;  /*   We only need n - 1 in most cases    */  __n--;  /*    Only sort array of at least two elements, all other are sorted  */  while(__n > 0) {#  if !defined(GENSORT_NOSMALL) && !defined(GENSORT_SWAP)    /*  If __n is small enough, use straight insertion  */    if(__n < GENSORT_LIMIT) {      for(__j = 1 ; __j <= __n ; __j++) {	GENSORT_TYPE __save;#   ifdef GENSORT_GETELEMENT	__save = GENSORT_GETELEMENT(__array,__j);#   else	__save = __array[__j];#   endif	for(__i = __j - 1 ; __i >= 0 &&#   ifdef GENSORT_GETELEMENT	    (GENSORT_COMPAREKEYS((GENSORT_GETKEY(__save)),				 (GENSORT_GETKEY((GENSORT_GETELEMENT(__array,								     __i))))))#   else	    (GENSORT_COMPAREKEYS((GENSORT_GETKEY(__save)),				 (GENSORT_GETKEY((__array[__i])))))#   endif	      ; __i--) {#   ifdef GENSORT_GETELEMENT	  GENSORT_GETELEMENT(__array,(__i + 1)) =	    GENSORT_GETELEMENT(__array,__i);#   else	  __array[__i + 1] = __array[__i];#   endif	}#   ifdef GENSORT_GETELEMENT	GENSORT_GETELEMENT(__array,(__i + 1)) = __save;#   else	__array[__i + 1] = __save;#   endif      }      return;    }#  endif    /*   Preset pointers   */    __i = 0;    /*  Index to first element  */    __j = __n;  /*  Index to last element   */#  ifdef GENSORT_GETELEMENT    /*      Get middle element      */    __x = GENSORT_GETKEY(GENSORT_GETELEMENT(__array,((__n + 1) >> 1)));#  else    /*      Get middle element      */    __x = GENSORT_GETKEY((__array[ (__n + 1) >> 1]));#  endif    do {#  ifdef GENSORT_GETELEMENT      while(GENSORT_COMPAREKEYS((GENSORT_GETKEY(                (GENSORT_GETELEMENT(__array,__i)))),__x))	__i++;      while(GENSORT_COMPAREKEYS(__x,(GENSORT_GETKEY(		(GENSORT_GETELEMENT(__array,__j))))))	__j--;#  else      while(GENSORT_COMPAREKEYS((GENSORT_GETKEY((__array[__i]))),__x))	__i++;      while(GENSORT_COMPAREKEYS(__x,(GENSORT_GETKEY((__array[__j])))))	__j--;#  endif      if(__i > __j) break;#  ifdef GENSORT_SWAP      {        /*    Use user supplied macro   */        GENSORT_SWAP(__array,__i,__j);      }      __i++; __j--;#  else      {	GENSORT_TYPE __temp; /*   Only needed temporary  */	/*     Exchange elements   */        __temp = __array[__i];  __array[__i++] = __array[__j];	__array[__j--] = __temp;      }#  endif    } while(__i <= __j);    if(__j < (__n - __i)) {      /*  Call recursive with left part  */      if(0 < __j)	GENSORT_NAME(__array,(__j + 1) GENSORT_ARGS);      /*  Loop again with right part   */#  ifdef GENSORT_GETELEMENT      __array = &GENSORT_GETELEMENT(__array,__i);#  else      __array += __i;#  endif      __n -= __i;    } else {      /*  Call recursive with right part  */      if(__i < __n)#  ifdef GENSORT_GETELEMENT	GENSORT_NAME(&GENSORT_GETELEMENT(__array,__i),		     (__n + 1 - __i) GENSORT_ARGS);#  else	GENSORT_NAME(__array + __i,__n + 1 - __i GENSORT_ARGS);#  endif      /*  Loop again with left part   */      __n = __j;    }  }  return;}# else#  ifdef GENSORT_GETELEMENT#   error GENSORT.H: Cannot use GENSORT_GETELEMENT with pointers!#  endif/* ******   Quicksort with pointers     *********** */void GENSORT_NAME(GENSORT_TYPE *__array,GENSORT_INTTYPE __n GENSORT_ARGSPROTO){  register GENSORT_TYPE *__arrayi;  register GENSORT_TYPE *__arrayj;  GENSORT_KEYTYPE __x;  /*   We only need __n - 1 in most cases    */  __n--;  /*    Only sort array of at least two elements, all other are sorted  */  while(__n > 0) {#  if !defined(GENSORT_NOSMALL) && !defined(GENSORT_SWAP)    /*  If __n is small enough, use straight insertion  */    if(__n < GENSORT_LIMIT) {      for(__arrayj = &__array[1] ; __arrayj <= &__array[__n] ; __arrayj++) {	GENSORT_TYPE __save;	__save = *__arrayj;	for(__arrayi = __arrayj - 1 ; __arrayi >= __array &&	    (GENSORT_COMPAREKEYS((GENSORT_GETKEY(__save)),				 (GENSORT_GETKEY((*__arrayi)))))	      ; __arrayi--) {	  __arrayi[1] = *__arrayi;	}	__arrayi[1] = __save;      }      return;    }#  endif    /*   Preset pointers   */    __arrayi = __array;        /*  Pointer to first element  */    __arrayj = __array + __n;  /*  Pointer to last element   */    /*      Get middle element      */    __x = GENSORT_GETKEY( (__array[ (__n + 1) >> 1]) );    do {      while(GENSORT_COMPAREKEYS((GENSORT_GETKEY((*__arrayi))),__x))	__arrayi++;      while(GENSORT_COMPAREKEYS(__x,(GENSORT_GETKEY((*__arrayj)))))	__arrayj--;      if(__arrayi > __arrayj)	break;#  ifdef GENSORT_SWAP      {        /*    Use user supplied macro   */        GENSORT_SWAP(__array,(__arrayi - __array),(__arrayj - __array));      }      __arrayi++; __arrayj--;#  else      {	GENSORT_TYPE __temp; /*   Only needed temporary  */	/*     Exchange elements   */	__temp = *__arrayi;  *__arrayi++ = *__arrayj;  *__arrayj-- = __temp;      }#  endif    } while(__arrayi <= __arrayj);    if( (__arrayj - __array) < (__array - __arrayi + __n)) {      /*  Call recursive with left part  */      if(__array < __arrayj)	GENSORT_NAME(__array,__arrayj - __array + 1 GENSORT_ARGS);      /*  Loop again with right part   */      __n -= __arrayi - __array;      __array = __arrayi;    } else {      /*  Call recursive with right part  */      if(__arrayi < (__array + __n))	GENSORT_NAME(__arrayi,__array + __n + 1 - __arrayi GENSORT_ARGS);      /*  Loop again with left part   */      __n = __arrayj - __array;    }  }  return;}# endif#else/* ******   Heapsort routine              *********** */#ifdef GENSORT_SWAP# error "gensort.h": Cannot use GENSORT_SWAP and GENSORT_HEAPSORT!#endif/*   Preprocessor macro to generate second routine    *//*    with temporary name (sift routine).             */#define GENSORT_TEMPNAME(name)   GENSORT_TEMPNAME2(name)#define GENSORT_TEMPNAME2(name)  name##__sift/* ****    Now the main heapsort routine  **** */void GENSORT_NAME(GENSORT_TYPE *__array,GENSORT_INTTYPE __n GENSORT_ARGS){  register GENSORT_INTTYPE __i;  /*   Prototype for sift routine (Compiler does not like "static" here!  */  void GENSORT_TEMPNAME(GENSORT_NAME)    (GENSORT_TYPE *,GENSORT_INTTYPE,GENSORT_INTTYPE GENSORT_ARGS);  /*  Build up heap    */  for(__i = (__n >> 1) ; __i > 0 ; )    GENSORT_TEMPNAME(GENSORT_NAME) (__array,--__i,__n GENSORT_ARGS);  for(__i = __n - 1 ; __i > 0 ; ) {    {      GENSORT_TYPE __temp;#  ifdef GENSORT_GETELEMENT      __temp = GENSORT_GETELEMENT(__array,0);      GENSORT_GETELEMENT(__array,0) = GENSORT_GETELEMENT(__array,__i);      GENSORT_GETELEMENT(__array,i) = __temp;#  else      /*     Exchange elements   */      __temp = *__array;  *__array = __array[__i];  __array[__i] = __temp;#  endif    }    /*   Call sift routine    */    GENSORT_TEMPNAME(GENSORT_NAME) (__array,0,__i-- GENSORT_ARGS);  }  return;}/* ****   Sift routine is global! Compiler does not like static here  **** */void GENSORT_TEMPNAME(GENSORT_NAME) (GENSORT_TYPE *__array,GENSORT_INTTYPE __i,				     GENSORT_INTTYPE __n GENSORT_ARGS){  register GENSORT_INTTYPE __j;  GENSORT_TYPE __temp;  /*   Get first element to sink in heap   */# ifdef GENSORT_GETELEMENT  __temp = GENSORT_GETELEMENT(__array,__i);# else  __temp = __array[__i];# endif  while( (__j = ((__i << 1) + 1)) < __n) {# ifdef GENSORT_GETELEMENT    if( (__j < (__n - 1)) && (GENSORT_COMPAREKEYS((GENSORT_GETKEY(		GENSORT_GETELEMENT(__array,__j))),(GENSORT_GETKEY(		GENSORT_GETELEMENT(__array,(__j + 1)))))) )      ++__j;    if( !(GENSORT_COMPAREKEYS((GENSORT_GETKEY(__temp)),(GENSORT_GETKEY(		GENSORT_GETELEMENT(__array,__j))))) )      break;    /*   Copy lower element to top    */    GENSORT_GETELEMENT(__array,__i) = GENSORT_GETELEMENT(__array,__j);    __i = __j;# else    if( (__j < (__n - 1)) && (GENSORT_COMPAREKEYS((GENSORT_GETKEY((__array[__j]))),            (GENSORT_GETKEY((__array[__j + 1]))))) )      ++__j;    if( !(GENSORT_COMPAREKEYS((GENSORT_GETKEY(__temp)),	   (GENSORT_GETKEY((__array[__j]))))) )      break;    /*   Copy lower element to top   */    __array[__i] = __array[__j];    __i = __j;# endif  }# ifdef GENSORT_GETELEMENT  /*   Now the first element has reached its place   */  GENSORT_GETELEMENTS(__array,__i) = __temp;# else  /*   Now the first element has reached its place   */  __array[__i] = __temp;# endif  return;}# undef GENSORT_TEMPNAME# undef GENSORT_TEMPNAME2#endif/* *******  Undefine all symbols for reuse    ****** */#undef GENSORT_NAME#undef GENSORT_TYPE#undef GENSORT_KEYTYPE#undef GENSORT_GETKEY#undef GENSORT_COMPAREKEYS#undef GENSORT_HEAPSORT#undef GENSORT_ARGSPROTO#undef GENSORT_ARGS#undef GENSORT_LIMIT#undef GENSORT_NOSMALL#undef GENSORT_SWAP#undef GENSORT_GETELEMENT#undef GENSORT_NISINT#undef GENSORT_INTTYPE

⌨️ 快捷键说明

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