/misc/src/release/graphviz-2.18-1/src/graphviz-2.18/lib/circogen/deglist.c

Go to the documentation of this file.
00001 /* $Id: deglist.c,v 1.2 2005/02/24 00:57:33 ellson Exp $ $Revision: 1.2 $ */
00002 /* vim:set shiftwidth=4 ts=8: */
00003 
00004 /**********************************************************
00005 *      This software is part of the graphviz package      *
00006 *                http://www.graphviz.org/                 *
00007 *                                                         *
00008 *            Copyright (c) 1994-2004 AT&T Corp.           *
00009 *                and is licensed under the                *
00010 *            Common Public License, Version 1.0           *
00011 *                      by AT&T Corp.                      *
00012 *                                                         *
00013 *        Information and Software Systems Research        *
00014 *              AT&T Research, Florham Park NJ             *
00015 **********************************************************/
00016 
00017 
00018 #include <deglist.h>
00019 #include <circular.h>
00020 #include <blockpath.h>
00021 #include <assert.h>
00022 
00023 typedef struct {
00024     Dtlink_t link;
00025     int deg;
00026     Agnode_t *np;               /* linked list of nodes of same degree */
00027 } degitem;
00028 
00029 static degitem *mkItem(Dt_t * d, degitem * obj, Dtdisc_t * disc)
00030 {
00031     degitem *ap = GNEW(degitem);
00032 
00033     ap->np = NULL;
00034     ap->deg = obj->deg;
00035     return ap;
00036 }
00037 
00038 static void freeItem(Dt_t * d, degitem * obj, Dtdisc_t * disc)
00039 {
00040     free(obj);
00041 }
00042 
00043 static int cmpDegree(Dt_t * d, int *key1, int *key2, Dtdisc_t * disc)
00044 {
00045     if (*key1 < *key2)
00046         return -1;
00047     else if (*key1 > *key2)
00048         return 1;
00049     else
00050         return 0;
00051 }
00052 
00053 static Dtdisc_t nodeDisc = {
00054     offsetof(degitem, deg),     /* key */
00055     sizeof(int),                /* size */
00056     offsetof(degitem, link),    /* link */
00057     (Dtmake_f) mkItem,
00058     (Dtfree_f) freeItem,
00059     (Dtcompar_f) cmpDegree,
00060     (Dthash_f) 0,
00061     (Dtmemory_f) 0,
00062     (Dtevent_f) 0
00063 };
00064 
00065 /* mkDeglist:
00066  * Create an empty list of nodes.
00067  */
00068 deglist_t *mkDeglist(void)
00069 {
00070     deglist_t *s = dtopen(&nodeDisc, Dtoset);
00071     return s;
00072 }
00073 
00074 /* freeDeglist:
00075  * Delete the node list.
00076  * Nodes are not deleted.
00077  */
00078 void freeDeglist(deglist_t * s)
00079 {
00080     dtclose(s);
00081 }
00082 
00083 /* insertDeglist:
00084  * Add a node to the node list.
00085  * Nodes are kept sorted by DEGREE, smallest degrees first.
00086  */
00087 void insertDeglist(deglist_t * ns, Agnode_t * n)
00088 {
00089     degitem key;
00090     degitem *kp;
00091 
00092     key.deg = DEGREE(n);
00093     kp = dtinsert(ns, &key);
00094     ND_next(n) = kp->np;
00095     kp->np = n;
00096 }
00097 
00098 /* removeDeglist:
00099  * Remove n from list, if it is in the list.
00100  */
00101 void removeDeglist(deglist_t * list, Agnode_t * n)
00102 {
00103     degitem key;
00104     degitem *ip;
00105     Agnode_t *np;
00106     Agnode_t *prev;
00107 
00108     key.deg = DEGREE(n);
00109     ip = (degitem *) dtsearch(list, &key);
00110     assert(ip);
00111     if (ip->np == n) {
00112         ip->np = ND_next(n);
00113         if (ip->np == NULL)
00114             dtdelete(list, ip);
00115     } else {
00116         prev = ip->np;
00117         np = ND_next(prev);
00118         while (np && (np != n)) {
00119             prev = np;
00120             np = ND_next(np);
00121         }
00122         if (np)
00123             ND_next(prev) = ND_next(np);
00124     }
00125 }
00126 
00127 /* firstDeglist:
00128  * Return the first node in the list (smallest degree)
00129  * Remove from list.
00130  * If the list is empty, return NULL
00131  */
00132 Agnode_t *firstDeglist(deglist_t * list)
00133 {
00134     degitem *ip;
00135     Agnode_t *np;
00136 
00137     ip = (degitem *) dtfirst(list);
00138     if (ip) {
00139         np = ip->np;
00140         ip->np = ND_next(np);
00141         if (ip->np == NULL)
00142             dtdelete(list, ip);
00143         return np;
00144     } else
00145         return 0;
00146 }
00147 
00148 #ifdef DEBUG
00149 void printDeglist(deglist_t * dl)
00150 {
00151     degitem *ip;
00152     node_t *np;
00153     fprintf(stderr, " dl:\n");
00154     for (ip = (degitem *) dtfirst(dl); ip; ip = (degitem *) dtnext(dl, ip)) {
00155         np = ip->np;
00156         if (np)
00157             fprintf(stderr, " (%d)", ip->deg);
00158         for (; np; np = ND_next(np)) {
00159             fprintf(stderr, " %s", np->name);
00160         }
00161         fprintf(stderr, "\n");
00162     }
00163 
00164 }
00165 #endif

Generated on Mon Mar 31 19:03:23 2008 for Graphviz by  doxygen 1.5.1