the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* Fibonacci heaps are somewhat complex, but, there's an
- article in DDJ on them that explains them pretty well:
+/* Fibonacci heaps are somewhat complex, but, there's an article in
+ DDJ that explains them pretty well:
http://www.ddj.com/articles/1997/9701/9701o/9701o.htm?topic=algoritms
- Introduction to algorithms by Corman and Rivest also goes over
- them.
+ Introduction to algorithms by Corman and Rivest also goes over them.
The original paper that introduced them is "Fibonacci heaps and their
uses in improved network optimization algorithms" by Tarjan and
ExtractMin: O(lg n) amortized. O(n) worst case.
DecreaseKey: O(1) amortized. O(lg n) worst case.
Insert: O(2) amortized. O(1) actual.
- Union: O(1) amortized. O(1) actual.
-
-
-*/
+ Union: O(1) amortized. O(1) actual. */
#ifndef _FIBHEAP_H_
#define _FIBHEAP_H_
#include <ansidecl.h>
+typedef long fibheapkey_t;
+
typedef struct fibheap
{
size_t nodes;
struct fibnode *min;
struct fibnode *root;
} *fibheap_t;
-typedef long fibheapkey_t;
+
typedef struct fibnode
{
struct fibnode *parent;
struct fibnode *child;
struct fibnode *left;
struct fibnode *right;
- unsigned int degree : sizeof(size_t) * CHAR_BIT - 2;
- unsigned int mark:1;
fibheapkey_t key;
void *data;
+ unsigned int degree : 31;
+ unsigned int mark : 1;
} *fibnode_t;
extern fibheap_t fibheap_new PARAMS ((void));
extern fibnode_t fibheap_insert PARAMS ((fibheap_t, fibheapkey_t, void *));
extern int fibheap_empty PARAMS ((fibheap_t));
extern fibheapkey_t fibheap_min_key PARAMS ((fibheap_t));
-extern fibheapkey_t fibheap_replace_key PARAMS ((fibheap_t, fibnode_t, fibheapkey_t));
-extern void *fibheap_replace_key_data PARAMS ((fibheap_t, fibnode_t, fibheapkey_t, void *));
+extern fibheapkey_t fibheap_replace_key PARAMS ((fibheap_t, fibnode_t,
+ fibheapkey_t));
+extern void *fibheap_replace_key_data PARAMS ((fibheap_t, fibnode_t,
+ fibheapkey_t, void *));
extern void *fibheap_extract_min PARAMS ((fibheap_t));
extern void *fibheap_min PARAMS ((fibheap_t));
extern void *fibheap_replace_data PARAMS ((fibheap_t, fibnode_t, void *));
extern void *fibheap_delete_node PARAMS ((fibheap_t, fibnode_t));
extern void fibheap_delete PARAMS ((fibheap_t));
extern fibheap_t fibheap_union PARAMS ((fibheap_t, fibheap_t));
+
#endif /* _FIBHEAP_H_ */
EOF
- case "${host}" in
- *-*-cygwin*)
- cat >> confdefs.h <<\EOF
-#define HAVE_SYS_ERRLIST 1
-EOF
-
- ;;
- esac
-
setobjs=yes
fi
+case "${host}" in
+ *-*-cygwin*)
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYS_ERRLIST 1
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYS_NERR 1
+EOF
+
+ ;;
+esac
+
if test -z "${setobjs}"; then
case "${host}" in
# We haven't set the list of objects yet. Use the standard autoconf
# tests. This will only work if the compiler works.
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1929: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:1933: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
cat > conftest.$ac_ext << EOF
-#line 1940 "configure"
+#line 1944 "configure"
#include "confdefs.h"
main(){return(0);}
EOF
-if { (eval echo configure:1945: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1949: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
ac_cv_prog_cc_works=yes
# If we can't run a trivial program, we are probably using a cross compiler.
if (./conftest; exit) 2>/dev/null; then
{ echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:1971: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:1975: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
cross_compiling=$ac_cv_prog_cc_cross
for ac_func in $funcs
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1978: checking for $ac_func" >&5
+echo "configure:1982: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1983 "configure"
+#line 1987 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
; return 0; }
EOF
-if { (eval echo configure:2006: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2010: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
-echo "configure:2033: checking whether alloca needs Cray hooks" >&5
+echo "configure:2037: checking whether alloca needs Cray hooks" >&5
if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2038 "configure"
+#line 2042 "configure"
#include "confdefs.h"
#if defined(CRAY) && ! defined(CRAY2)
webecray
if test $ac_cv_os_cray = yes; then
for ac_func in _getb67 GETB67 getb67; do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2063: checking for $ac_func" >&5
+echo "configure:2067: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2068 "configure"
+#line 2072 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
; return 0; }
EOF
-if { (eval echo configure:2091: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2095: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
fi
echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
-echo "configure:2117: checking stack direction for C alloca" >&5
+echo "configure:2121: checking stack direction for C alloca" >&5
if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_cv_c_stack_direction=0
else
cat > conftest.$ac_ext <<EOF
-#line 2125 "configure"
+#line 2129 "configure"
#include "confdefs.h"
find_stack_direction ()
{
exit (find_stack_direction() < 0);
}
EOF
-if { (eval echo configure:2144: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2148: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_c_stack_direction=1
else
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:2165: checking for ANSI C header files" >&5
+echo "configure:2169: checking for ANSI C header files" >&5
if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2170 "configure"
+#line 2174 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
#include <float.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2178: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2182: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 2195 "configure"
+#line 2199 "configure"
#include "confdefs.h"
#include <string.h>
EOF
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 2213 "configure"
+#line 2217 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
:
else
cat > conftest.$ac_ext <<EOF
-#line 2234 "configure"
+#line 2238 "configure"
#include "confdefs.h"
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
exit (0); }
EOF
-if { (eval echo configure:2245: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2249: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
:
else
fi
echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-echo "configure:2269: checking for pid_t" >&5
+echo "configure:2273: checking for pid_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2274 "configure"
+#line 2278 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
ac_safe=`echo "vfork.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for vfork.h""... $ac_c" 1>&6
-echo "configure:2303: checking for vfork.h" >&5
+echo "configure:2307: checking for vfork.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2308 "configure"
+#line 2312 "configure"
#include "confdefs.h"
#include <vfork.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2313: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2317: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
fi
echo $ac_n "checking for working vfork""... $ac_c" 1>&6
-echo "configure:2338: checking for working vfork" >&5
+echo "configure:2342: checking for working vfork" >&5
if eval "test \"`echo '$''{'ac_cv_func_vfork_works'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
echo $ac_n "checking for vfork""... $ac_c" 1>&6
-echo "configure:2344: checking for vfork" >&5
+echo "configure:2348: checking for vfork" >&5
if eval "test \"`echo '$''{'ac_cv_func_vfork'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2349 "configure"
+#line 2353 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char vfork(); below. */
; return 0; }
EOF
-if { (eval echo configure:2372: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2376: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_vfork=yes"
else
ac_cv_func_vfork_works=$ac_cv_func_vfork
else
cat > conftest.$ac_ext <<EOF
-#line 2394 "configure"
+#line 2398 "configure"
#include "confdefs.h"
/* Thanks to Paul Eggert for this test. */
#include <stdio.h>
}
}
EOF
-if { (eval echo configure:2489: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2493: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_func_vfork_works=yes
else
fi
for v in $vars; do
echo $ac_n "checking for $v""... $ac_c" 1>&6
-echo "configure:2516: checking for $v" >&5
+echo "configure:2520: checking for $v" >&5
if eval "test \"`echo '$''{'libiberty_cv_var_$v'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2521 "configure"
+#line 2525 "configure"
#include "confdefs.h"
int *p;
int main() {
extern int $v; p = &$v;
; return 0; }
EOF
-if { (eval echo configure:2528: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2532: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "libiberty_cv_var_$v=yes"
else
for ac_func in $checkfuncs
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2554: checking for $ac_func" >&5
+echo "configure:2558: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2559 "configure"
+#line 2563 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
; return 0; }
EOF
-if { (eval echo configure:2582: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2586: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2612: checking for $ac_hdr" >&5
+echo "configure:2616: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2617 "configure"
+#line 2621 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2622: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2626: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
for ac_func in getpagesize
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2651: checking for $ac_func" >&5
+echo "configure:2655: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2656 "configure"
+#line 2660 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
; return 0; }
EOF
-if { (eval echo configure:2679: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2683: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
done
echo $ac_n "checking for working mmap""... $ac_c" 1>&6
-echo "configure:2704: checking for working mmap" >&5
+echo "configure:2708: checking for working mmap" >&5
if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_cv_func_mmap_fixed_mapped=no
else
cat > conftest.$ac_ext <<EOF
-#line 2712 "configure"
+#line 2716 "configure"
#include "confdefs.h"
/* Thanks to Mike Haertel and Jim Avera for this test.
}
EOF
-if { (eval echo configure:2852: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2856: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_func_mmap_fixed_mapped=yes
else
echo $ac_n "checking for working strncmp""... $ac_c" 1>&6
-echo "configure:2876: checking for working strncmp" >&5
+echo "configure:2880: checking for working strncmp" >&5
if eval "test \"`echo '$''{'ac_cv_func_strncmp_works'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_cv_func_strncmp_works=no
else
cat > conftest.$ac_ext <<EOF
-#line 2884 "configure"
+#line 2888 "configure"
#include "confdefs.h"
/* Test by Jim Wilson and Kaveh Ghazi.
}
EOF
-if { (eval echo configure:2945: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2949: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_func_strncmp_works=yes
else
-
/* A Fibonacci heap datatype.
Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Daniel Berlin (dan@cgsoftware.com).
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* Fibonacci heaps */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#ifdef HAVE_LIMITS_H
#include <limits.h>
+#endif
+#ifdef HAVE_STDLIB_H
#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
#include "libiberty.h"
#include "fibheap.h"
+#define FIBHEAPKEY_MIN LONG_MIN
+
static void fibheap_init PARAMS ((fibheap_t));
static void fibheap_ins_root PARAMS ((fibheap_t, fibnode_t));
static void fibheap_rem_root PARAMS ((fibheap_t, fibnode_t));
static void fibheap_cascading_cut PARAMS ((fibheap_t, fibnode_t));
static fibnode_t fibheap_extr_min_node PARAMS ((fibheap_t));
static int fibheap_compare PARAMS ((fibheap_t, fibnode_t, fibnode_t));
-static int fibheap_comp_data PARAMS ((fibheap_t, fibheapkey_t, void *, fibnode_t));
+static int fibheap_comp_data PARAMS ((fibheap_t, fibheapkey_t, void *,
+ fibnode_t));
static fibnode_t fibnode_new PARAMS ((void));
static void fibnode_init PARAMS ((fibnode_t));
static void fibnode_insert_after PARAMS ((fibnode_t, fibnode_t));
#define fibnode_insert_before(a, b) fibnode_insert_after (a->left, b)
static fibnode_t fibnode_remove PARAMS ((fibnode_t));
+\f
+/* Initialize the passed in fibonacci heap. */
+static inline void
+fibheap_init (heap)
+ fibheap_t heap;
+{
+ heap->nodes = 0;
+ heap->min = NULL;
+ heap->root = NULL;
+}
+
/* Create a new fibonacci heap. */
fibheap_t
fibheap_new ()
return result;
}
-/* Initialize the passed in fibonacci heap. */
-static void
-fibheap_init (heap)
+/* Initialize the passed in fibonacci heap node. */
+static inline void
+fibnode_init (node)
+ fibnode_t node;
+{
+ node->degree = 0;
+ node->mark = 0;
+ node->parent = NULL;
+ node->child = NULL;
+ node->left = node;
+ node->right = node;
+ node->data = NULL;
+}
+
+/* Create a new fibonacci heap node. */
+static inline fibnode_t
+fibnode_new ()
+{
+ fibnode_t e;
+
+ if ((e = xmalloc (sizeof *e)) == NULL)
+ return NULL;
+
+ fibnode_init (e);
+
+ return e;
+}
+
+static inline int
+fibheap_compare (heap, a, b)
+ fibheap_t heap ATTRIBUTE_UNUSED;
+ fibnode_t a;
+ fibnode_t b;
+{
+ if (a->key < b->key)
+ return -1;
+ if (a->key > b->key)
+ return 1;
+ return 0;
+}
+
+static inline int
+fibheap_comp_data (heap, key, data, b)
fibheap_t heap;
+ fibheapkey_t key;
+ void *data;
+ fibnode_t b;
{
- heap->nodes = 0;
- heap->min = NULL;
- heap->root = NULL;
+ struct fibnode a;
+
+ a.key = key;
+ a.data = data;
+
+ return fibheap_compare (heap, &a, b);
}
/* Insert DATA, with priority KEY, into HEAP. */
void *data;
{
fibnode_t node;
+
/* Create the new node, if we fail, return NULL. */
if ((node = fibnode_new ()) == NULL)
return NULL;
+
/* Set the node's data. */
node->data = data;
node->key = key;
/* Insert it into the root list. */
fibheap_ins_root (heap, node);
- /* If their was no minimum, or this key is less than the min, it's the new
- min. */
+ /* If their was no minimum, or this key is less than the min,
+ it's the new min. */
if (heap->min == NULL || node->key < heap->min->key)
heap->min = node;
fibheap_t heapa;
fibheap_t heapb;
{
- fibnode_t temp;
+ fibnode_t a_root, b_root, temp;
/* If one of the heaps is empty, the union is just the other heap. */
- if (heapa->root == NULL || heapb->root == NULL)
+ if ((a_root = heapa->root) == NULL)
{
- if (heapa->root == NULL)
- {
- free (heapa);
- return heapb;
- }
- else
- {
- free (heapb);
- return heapa;
- }
+ free (heapa);
+ return heapb;
+ }
+ if ((b_root = heapb->root) == NULL)
+ {
+ free (heapb);
+ return heapa;
}
+
/* Merge them to the next nodes on the opposite chain. */
- heapa->root->left->right = heapb->root;
- heapb->root->left->right = heapa->root;
- temp = heapa->root->left;
- heapa->root->left = heapb->root->left;
- heapb->root->left = temp;
+ a_root->left->right = b_root;
+ b_root->left->right = a_root;
+ temp = a_root->left;
+ a_root->left = b_root->left;
+ b_root->left = temp;
heapa->nodes += heapb->nodes;
/* And set the new minimum, if it's changed. */
fibheap_t heap;
{
fibnode_t z;
- void *ret;
+ void *ret = NULL;
- ret = NULL;
/* If we don't have a min set, it means we have no nodes. */
if (heap->min != NULL)
{
return ret;
}
-/* Replace the DATA associated with NODE. */
-void *
-fibheap_replace_data (heap, node, data)
- fibheap_t heap;
- fibnode_t node;
- void *data;
-{
- return fibheap_replace_key_data (heap, node, node->key, data);
-}
-
-/* Replace the KEY associated with NODE. */
-fibheapkey_t
-fibheap_replace_key (heap, node, key)
- fibheap_t heap;
- fibnode_t node;
- fibheapkey_t key;
-{
- int ret;
-
- ret = node->key;
- (void) fibheap_replace_key_data (heap, node, key, node->data);
-
- return ret;
-}
-
/* Replace both the KEY and the DATA associated with NODE. */
void *
fibheap_replace_key_data (heap, node, key, data)
return odata;
}
+/* Replace the DATA associated with NODE. */
+void *
+fibheap_replace_data (heap, node, data)
+ fibheap_t heap;
+ fibnode_t node;
+ void *data;
+{
+ return fibheap_replace_key_data (heap, node, node->key, data);
+}
+
+/* Replace the KEY associated with NODE. */
+fibheapkey_t
+fibheap_replace_key (heap, node, key)
+ fibheap_t heap;
+ fibnode_t node;
+ fibheapkey_t key;
+{
+ int okey = node->key;
+ fibheap_replace_key_data (heap, node, key, node->data);
+ return okey;
+}
+
/* Delete NODE from HEAP. */
void *
fibheap_delete_node (heap, node)
fibheap_t heap;
fibnode_t node;
{
- void *k;
+ void *ret = node->data;
+
/* To perform delete, we just make it the min key, and extract. */
- k = node->data;
- fibheap_replace_key (heap, node, LONG_MIN);
+ fibheap_replace_key (heap, node, FIBHEAPKEY_MIN);
fibheap_extract_min (heap);
- return k;
+ return ret;
}
/* Delete HEAP. */
return heap->nodes == 0;
}
-
/* Extract the minimum node of the heap. */
static fibnode_t
fibheap_extr_min_node (heap)
fibheap_t heap;
{
- fibnode_t ret;
+ fibnode_t ret = heap->min;
fibnode_t x, y, orig;
- ret = heap->min;
-
- orig = NULL;
/* Attach the child list of the minimum node to the root list of the heap.
If there is no child list, we don't do squat. */
- for (x = ret->child; x != orig && x != NULL;)
+ for (x = ret->child, orig = NULL; x != orig && x != NULL; x = y)
{
if (orig == NULL)
orig = x;
y = x->right;
x->parent = NULL;
fibheap_ins_root (heap, x);
- x = y;
}
+
/* Remove the old root. */
fibheap_rem_root (heap, ret);
heap->nodes--;
+
/* If we are left with no nodes, then the min is NULL. */
if (heap->nodes == 0)
heap->min = NULL;
node->right = node;
return;
}
- /* Otherwise, insert it in the circular root list between the root and it's
- right node. */
+
+ /* Otherwise, insert it in the circular root list between the root
+ and it's right node. */
fibnode_insert_after (heap->root, node);
}
}
}
-
-static fibnode_t
-fibnode_new ()
-{
- fibnode_t e;
-
- if ((e = xmalloc (sizeof *e)) == NULL)
- return NULL;
-
- fibnode_init (e);
-
- return e;
-}
-
-static void
-fibnode_init (node)
- fibnode_t node;
-{
- node->degree = 0;
- node->mark = 0;
- node->parent = NULL;
- node->child = NULL;
- node->left = node;
- node->right = node;
- node->data = NULL;
-}
-
static void
fibnode_insert_after (a, b)
fibnode_t a;
}
}
-
static fibnode_t
fibnode_remove (node)
fibnode_t node;
return ret;
}
-
-static int
-fibheap_compare (heap, a, b)
- fibheap_t heap ATTRIBUTE_UNUSED;
- fibnode_t a;
- fibnode_t b;
-{
- if (a->key < b->key)
- return -1;
- if (a->key > b->key)
- return 1;
- return 0;
-}
-
-static int
-fibheap_comp_data (heap, key, data, b)
- fibheap_t heap;
- fibheapkey_t key;
- void *data;
- fibnode_t b;
-{
- struct fibnode a;
-
- a.key = key;
- a.data = data;
-
- return fibheap_compare (heap, &a, b);
-}