forked from github/server
- Einfach Graphroutinen, für das Vorrücken.
- Kleine Erweiterungen für die vsets.
This commit is contained in:
parent
b5778f1cfd
commit
baee1ad457
|
@ -0,0 +1,209 @@
|
|||
/* vi: set ts=2:
|
||||
+-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||
| | Enno Rehling <enno@eressea-pbem.de>
|
||||
| Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de>
|
||||
| (c) 1998 - 2001 | Henning Peters <faroul@beyond.kn-bremen.de>
|
||||
| | Ingo Wilken <Ingo.Wilken@informatik.uni-oldenburg.de>
|
||||
+-------------------+ Stefan Reich <reich@halbling.de>
|
||||
|
||||
This program may not be used, modified or distributed
|
||||
without prior permission by the authors of Eressea.
|
||||
$Id: graph.c,v 1.1 2001/04/11 17:28:07 corwin Exp $
|
||||
*/
|
||||
|
||||
/* This is a very simple graph library. It is not optimized in any
|
||||
way, and relies heavily on the vset and stack routines. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "vset.h"
|
||||
#include "graph.h"
|
||||
|
||||
void
|
||||
graph_init(graph *g)
|
||||
{
|
||||
g->nodes = malloc(sizeof(vset));
|
||||
g->vertices = malloc(sizeof(vset));
|
||||
vset_init(g->nodes);
|
||||
vset_init(g->vertices);
|
||||
}
|
||||
|
||||
void
|
||||
graph_free(graph *g)
|
||||
{
|
||||
vset_destroy(g->nodes);
|
||||
vset_destroy(g->vertices);
|
||||
free(g->nodes);
|
||||
free(g->vertices);
|
||||
}
|
||||
|
||||
void
|
||||
graph_add_node(graph *g, node *n)
|
||||
{
|
||||
vset_add(g->nodes, n);
|
||||
}
|
||||
|
||||
void
|
||||
graph_add_vertex(graph *g, vertex *v)
|
||||
{
|
||||
vset_add(g->nodes, v);
|
||||
}
|
||||
|
||||
void
|
||||
graph_remove_node(graph *g, node *n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i != g->vertices->size; ++i) {
|
||||
vertex *v = g->vertices->data[i];
|
||||
if(v->node1 == n || v->node2 == n) {
|
||||
vset_erase(g->nodes, v);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
vset_erase(g->nodes, n);
|
||||
}
|
||||
|
||||
node *
|
||||
graph_find_node(graph *g, void *object)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i != g->nodes->size; ++i) {
|
||||
node *node = g->nodes->data[i];
|
||||
if(node->object == object) {
|
||||
return g->nodes->data[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The vset returned has to freed externally, else this will be a
|
||||
memory leak. */
|
||||
|
||||
vset *
|
||||
graph_neighbours(graph *g, node *n)
|
||||
{
|
||||
int i;
|
||||
vset *vs = malloc(sizeof(vset));
|
||||
vset_init(vs);
|
||||
for(i=0; i != g->vertices->size; ++i) {
|
||||
vertex *v = g->vertices->data[i];
|
||||
if(v->node1 == n && vset_count(vs, v->node2) == 0) {
|
||||
vset_add(vs, v->node2);
|
||||
} else if(v->node2 == n && vset_count(vs, v->node1) == 0) {
|
||||
vset_add(vs, v->node1);
|
||||
}
|
||||
}
|
||||
|
||||
return vs;
|
||||
}
|
||||
|
||||
void
|
||||
graph_resetmarkers(graph *g)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i != g->nodes->size; ++i) {
|
||||
node *node = g->nodes->data[i];
|
||||
node->marker = 0;
|
||||
}
|
||||
for(i=0; i != g->vertices->size; ++i) {
|
||||
vertex *vertex = g->vertices->data[i];
|
||||
vertex->marker = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* The vset returned has to freed externally, else this will be a
|
||||
memory leak. */
|
||||
|
||||
vset *
|
||||
graph_connected_nodes(graph *g, node *n)
|
||||
{
|
||||
vset *vs = malloc(sizeof(vset));
|
||||
vset *s = malloc(sizeof(vset));
|
||||
|
||||
vset_init(vs);
|
||||
vset_init(s);
|
||||
graph_resetmarkers(g);
|
||||
vset_add(vs, n);
|
||||
n->marker = 1;
|
||||
vset_add(s, n);
|
||||
while(s->size > 0) {
|
||||
node *n = vset_pop(s);
|
||||
vset *vs_nb = graph_neighbours(g, n);
|
||||
int i;
|
||||
for(i=0; i != vs_nb->size; ++i) {
|
||||
node *nb = vs_nb->data[i];
|
||||
if(nb->marker == 0) {
|
||||
nb->marker == 1;
|
||||
vset_add(vs, nb);
|
||||
vset_add(s, nb);
|
||||
}
|
||||
}
|
||||
vset_destroy(vs_nb);
|
||||
free(vs_nb);
|
||||
}
|
||||
|
||||
vset_destroy(s);
|
||||
free(s);
|
||||
|
||||
return vs;
|
||||
}
|
||||
|
||||
/* The vset returned has to freed externally, else this will be a
|
||||
memory leak. */
|
||||
|
||||
vset *
|
||||
graph_disjunct_graphs(graph *g)
|
||||
{
|
||||
vset *dg = malloc(sizeof(vset));
|
||||
vset *nodes = malloc(sizeof(vset));
|
||||
|
||||
vset_init(nodes);
|
||||
vset_concat(nodes, g->nodes);
|
||||
|
||||
while(nodes->size > 0) {
|
||||
graph *gt = malloc(sizeof(graph));
|
||||
vset s;
|
||||
int i;
|
||||
node *start;
|
||||
|
||||
graph_init(gt);
|
||||
start = vset_pop(nodes);
|
||||
graph_resetmarkers(g);
|
||||
graph_add_node(gt, start);
|
||||
start->marker = 1;
|
||||
vset_init(&s);
|
||||
vset_add(&s,start);
|
||||
while(s.size > 0) {
|
||||
vset *nbs = graph_neighbours(g,vset_pop(&s));
|
||||
for(i=0; i != nbs->size; ++i) {
|
||||
node *nb = nbs->data[i];
|
||||
if(nb->marker == 0) {
|
||||
nb->marker = 1;
|
||||
graph_add_node(gt,nb);
|
||||
vset_erase(nodes,nb);
|
||||
vset_add(&s,nb);
|
||||
}
|
||||
}
|
||||
vset_destroy(nbs); free(nbs);
|
||||
}
|
||||
|
||||
vset_destroy(&s);
|
||||
|
||||
for(i=0;i != g->vertices->size; ++i) {
|
||||
vertex *v = g->vertices->data[i];
|
||||
if(vset_count(g->nodes, v->node1)) {
|
||||
graph_add_vertex(gt,v);
|
||||
}
|
||||
}
|
||||
|
||||
vset_add(dg, gt);
|
||||
}
|
||||
|
||||
vset_destroy(nodes);
|
||||
free(nodes);
|
||||
|
||||
return dg;
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/* vi: set ts=2:
|
||||
+-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||
| | Enno Rehling <enno@eressea-pbem.de>
|
||||
| Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de>
|
||||
| (c) 1998 - 2001 | Henning Peters <faroul@beyond.kn-bremen.de>
|
||||
| | Ingo Wilken <Ingo.Wilken@informatik.uni-oldenburg.de>
|
||||
+-------------------+ Stefan Reich <reich@halbling.de>
|
||||
|
||||
This program may not be used, modified or distributed
|
||||
without prior permission by the authors of Eressea.
|
||||
$Id: graph.h,v 1.1 2001/04/11 17:28:07 corwin Exp $
|
||||
*/
|
||||
|
||||
#ifndef GRAPH_H
|
||||
#define GRAPH_H
|
||||
|
||||
typedef struct {
|
||||
int marker;
|
||||
void *object;
|
||||
} node;
|
||||
|
||||
typedef struct {
|
||||
int marker;
|
||||
node *node1;
|
||||
node *node2;
|
||||
} vertex;
|
||||
|
||||
typedef struct {
|
||||
vset *nodes;
|
||||
vset *vertices;
|
||||
} graph;
|
||||
|
||||
#endif
|
|
@ -1,6 +1,6 @@
|
|||
/* vi: set ts=2:
|
||||
*
|
||||
* $Id: vset.c,v 1.2 2001/01/26 16:19:41 enno Exp $
|
||||
* $Id: vset.c,v 1.3 2001/04/11 17:28:07 corwin Exp $
|
||||
* Eressea PB(E)M host Copyright (C) 1998-2000
|
||||
* Christian Schlittchen (corwin@amber.kn-bremen.de)
|
||||
* Katja Zedel (katze@felidae.kn-bremen.de)
|
||||
|
@ -41,7 +41,7 @@ vset_destroy(vset * s)
|
|||
int
|
||||
vset_erase(vset * s, void *item)
|
||||
{
|
||||
unsigned int i;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i != s->size; ++i)
|
||||
if (s->data[i] == item) {
|
||||
|
@ -51,10 +51,11 @@ vset_erase(vset * s, void *item)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
vset_add(vset * s, void *item)
|
||||
{
|
||||
unsigned int i;
|
||||
size_t i;
|
||||
|
||||
if (!s->data) {
|
||||
s->size = 0;
|
||||
|
@ -72,3 +73,35 @@ vset_add(vset * s, void *item)
|
|||
++s->size;
|
||||
return s->size - 1;
|
||||
}
|
||||
|
||||
void *
|
||||
vset_pop(vset *s)
|
||||
{
|
||||
if(s->size == 0) return NULL;
|
||||
s->size--;
|
||||
return data[s->size+1];
|
||||
}
|
||||
|
||||
int
|
||||
vset_count(vset *s, void *item)
|
||||
{
|
||||
size_t i;
|
||||
int c = 0;
|
||||
|
||||
for(i = 0; i != s->size; ++i) {
|
||||
if(s->data[i] == item) c++;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void
|
||||
vset_concat(vset *to, vset *from)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for(i=0; i != from->size; ++i) {
|
||||
vset_add(to, from->data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* vi: set ts=2:
|
||||
*
|
||||
* $Id: vset.h,v 1.2 2001/01/26 16:19:41 enno Exp $
|
||||
* $Id: vset.h,v 1.3 2001/04/11 17:28:07 corwin Exp $
|
||||
* Eressea PB(E)M host Copyright (C) 1998-2000
|
||||
* Christian Schlittchen (corwin@amber.kn-bremen.de)
|
||||
* Katja Zedel (katze@felidae.kn-bremen.de)
|
||||
|
@ -21,9 +21,12 @@ struct vset {
|
|||
size_t size;
|
||||
size_t maxsize;
|
||||
};
|
||||
void vset_init(vset * s);
|
||||
void vset_destroy(vset * s);
|
||||
unsigned int vset_add(vset * s, void *);
|
||||
int vset_erase(vset * s, void *);
|
||||
extern void vset_init(vset * s);
|
||||
extern void vset_destroy(vset * s);
|
||||
extern unsigned int vset_add(vset * s, void *);
|
||||
extern int vset_erase(vset * s, void *);
|
||||
extern int vset_count(vset *s, void *item);
|
||||
extern void *vset_pop(vset *s);
|
||||
extern void vset_concat(vset *to, vset *from);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue