206 строки
11 KiB
C
206 строки
11 KiB
C
/* Copyright 2010 IPB, INRIA & CNRS
|
|
**
|
|
** This file originally comes from the Scotch software package for
|
|
** static mapping, graph partitioning and sparse matrix ordering.
|
|
**
|
|
** This software is governed by the CeCILL-B license under French law
|
|
** and abiding by the rules of distribution of free software. You can
|
|
** use, modify and/or redistribute the software under the terms of the
|
|
** CeCILL-B license as circulated by CEA, CNRS and INRIA at the following
|
|
** URL: "http://www.cecill.info".
|
|
**
|
|
** As a counterpart to the access to the source code and rights to copy,
|
|
** modify and redistribute granted by the license, users are provided
|
|
** only with a limited warranty and the software's author, the holder of
|
|
** the economic rights, and the successive licensors have only limited
|
|
** liability.
|
|
**
|
|
** In this respect, the user's attention is drawn to the risks associated
|
|
** with loading, using, modifying and/or developing or reproducing the
|
|
** software by the user in light of its specific status of free software,
|
|
** that may mean that it is complicated to manipulate, and that also
|
|
** therefore means that it is reserved for developers and experienced
|
|
** professionals having in-depth computer knowledge. Users are therefore
|
|
** encouraged to load and test the software's suitability as regards
|
|
** their requirements in conditions enabling the security of their
|
|
** systems and/or data to be ensured and, more generally, to use and
|
|
** operate it in the same conditions as regards security.
|
|
**
|
|
** The fact that you are presently reading this means that you have had
|
|
** knowledge of the CeCILL-B license and that you accept its terms.
|
|
*/
|
|
/************************************************************/
|
|
/** **/
|
|
/** NAME : fibo.h **/
|
|
/** **/
|
|
/** AUTHOR : Francois PELLEGRINI **/
|
|
/** **/
|
|
/** FUNCTION : This module contains the definitions of **/
|
|
/** the generic Fibonacci trees. **/
|
|
/** **/
|
|
/** DATES : # Version 1.0 : from : 01 may 2010 **/
|
|
/** to 12 may 2010 **/
|
|
/** **/
|
|
/** NOTES : # Since this module has originally been **/
|
|
/** designed as a gain keeping data **/
|
|
/** structure for local optimization **/
|
|
/** algorithms, the computation of the **/
|
|
/** best node is only done when actually **/
|
|
/** searching for it. **/
|
|
/** This is most useful when many **/
|
|
/** insertions and deletions can take **/
|
|
/** place in the mean time. This is why **/
|
|
/** this data structure does not keep **/
|
|
/** track of the best node, unlike most **/
|
|
/** implementations do. **/
|
|
/** **/
|
|
/************************************************************/
|
|
|
|
/*
|
|
** The type and structure definitions.
|
|
*/
|
|
|
|
/* The doubly linked list structure. */
|
|
|
|
typedef struct FiboLink_ {
|
|
struct FiboNode_ * prevptr; /*+ Pointer to previous sibling element +*/
|
|
struct FiboNode_ * nextptr; /*+ Pointer to next sibling element +*/
|
|
} FiboLink;
|
|
|
|
/* The tree node data structure. The deflval
|
|
variable merges degree and flag variables.
|
|
The degree of a node is smaller than
|
|
"bitsizeof (INT)", so it can hold on an
|
|
"int". The flag value is stored in the
|
|
lowest bit of the value. */
|
|
|
|
|
|
typedef struct FiboNode_ {
|
|
struct FiboNode_ * pareptr; /*+ Pointer to parent element, if any +*/
|
|
struct FiboNode_ * chldptr; /*+ Pointer to first child element, if any +*/
|
|
FiboLink linkdat; /*+ Pointers to sibling elements +*/
|
|
int deflval; /*+ Lowest bit: flag value; other bits: degree value +*/
|
|
} FiboNode;
|
|
|
|
/* The tree data structure. The fake dummy node aims
|
|
at handling root node insertion without any test.
|
|
This is important as many insertions have to be
|
|
performed. */
|
|
|
|
typedef struct FiboTree_ {
|
|
FiboNode rootdat; /*+ Dummy node for fast root insertion +*/
|
|
FiboNode ** restrict degrtab; /*+ Consolidation array of size "bitsizeof (INT)" +*/
|
|
int (* cmpfptr) (const FiboNode * const, const FiboNode * const); /*+ Comparison routine +*/
|
|
} FiboTree;
|
|
|
|
/*
|
|
** The marco definitions.
|
|
*/
|
|
|
|
/* This is the core of the module. All of
|
|
the algorithms have been de-recursived
|
|
and written as macros. */
|
|
|
|
#define fiboTreeLinkAfter(o,n) do { \
|
|
FiboNode * nextptr; \
|
|
nextptr = (o)->linkdat.nextptr; \
|
|
(n)->linkdat.nextptr = nextptr; \
|
|
(n)->linkdat.prevptr = (o); \
|
|
nextptr->linkdat.prevptr = (n); \
|
|
(o)->linkdat.nextptr = (n); \
|
|
} while (0)
|
|
|
|
#define fiboTreeUnlink(n) do { \
|
|
(n)->linkdat.prevptr->linkdat.nextptr = (n)->linkdat.nextptr; \
|
|
(n)->linkdat.nextptr->linkdat.prevptr = (n)->linkdat.prevptr; \
|
|
} while (0)
|
|
|
|
#define fiboTreeAddMacro(t,n) do { \
|
|
(n)->pareptr = NULL; \
|
|
(n)->chldptr = NULL; \
|
|
(n)->deflval = 0; \
|
|
fiboTreeLinkAfter (&((t)->rootdat), (n)); \
|
|
} while (0)
|
|
|
|
#define fiboTreeMinMacro(t) (fiboTreeConsolidate (t))
|
|
|
|
#define fiboTreeCutChildren(t,n) do { \
|
|
FiboNode * chldptr; \
|
|
chldptr = (n)->chldptr; \
|
|
if (chldptr != NULL) { \
|
|
FiboNode * cendptr; \
|
|
cendptr = chldptr; \
|
|
do { \
|
|
FiboNode * nextptr; \
|
|
nextptr = chldptr->linkdat.nextptr; \
|
|
chldptr->pareptr = NULL; \
|
|
fiboTreeLinkAfter (&((t)->rootdat), chldptr); \
|
|
chldptr = nextptr; \
|
|
} while (chldptr != cendptr); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define fiboTreeDelMacro(t,n) do { \
|
|
FiboNode * pareptr; \
|
|
FiboNode * rghtptr; \
|
|
pareptr = (n)->pareptr; \
|
|
fiboTreeUnlink (n); \
|
|
fiboTreeCutChildren ((t), (n)); \
|
|
if (pareptr == NULL) \
|
|
break; \
|
|
rghtptr = (n)->linkdat.nextptr; \
|
|
while (1) { \
|
|
FiboNode * gdpaptr; \
|
|
int deflval; \
|
|
deflval = pareptr->deflval - 2; \
|
|
pareptr->deflval = deflval | 1; \
|
|
gdpaptr = pareptr->pareptr; \
|
|
pareptr->chldptr = (deflval <= 1) ? NULL : rghtptr; \
|
|
if (((deflval & 1) == 0) || (gdpaptr == NULL)) \
|
|
break; \
|
|
rghtptr = pareptr->linkdat.nextptr; \
|
|
fiboTreeUnlink (pareptr); \
|
|
pareptr->pareptr = NULL; \
|
|
fiboTreeLinkAfter (&((t)->rootdat), pareptr); \
|
|
pareptr = gdpaptr; \
|
|
} \
|
|
} while (0)
|
|
|
|
/*
|
|
** The function prototypes.
|
|
*/
|
|
|
|
/* This set of definitions allows the user
|
|
to specify whether he prefers to use
|
|
the fibonacci routines as macros or as
|
|
regular functions, for instance for
|
|
debugging. */
|
|
|
|
#define fiboTreeAdd fiboTreeAddMacro
|
|
/* #define fiboTreeDel fiboTreeDelMacro */
|
|
/* #define fiboTreeMin fiboTreeMinMacro */
|
|
|
|
#ifndef FIBO
|
|
#define static
|
|
#endif
|
|
|
|
int fiboTreeInit (FiboTree * const, int (*) (const FiboNode * const, const FiboNode * const));
|
|
void fiboTreeExit (FiboTree * const);
|
|
void fiboTreeFree (FiboTree * const);
|
|
FiboNode * fiboTreeConsolidate (FiboTree * const);
|
|
#ifndef fiboTreeAdd
|
|
void fiboTreeAdd (FiboTree * const, FiboNode * const);
|
|
#endif /* fiboTreeAdd */
|
|
#ifndef fiboTreeDel
|
|
void fiboTreeDel (FiboTree * const, FiboNode * const);
|
|
#endif /* fiboTreeDel */
|
|
#ifndef fiboTreeMin
|
|
FiboNode * fiboTreeMin (FiboTree * const);
|
|
#endif /* fiboTreeMin */
|
|
#ifdef FIBO_DEBUG
|
|
int fiboTreeCheck (const FiboTree * const);
|
|
static int fiboTreeCheck2 (const FiboNode * const);
|
|
#endif /* FIBO_DEBUG */
|
|
|
|
#undef static
|