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:
|
/* 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
|
* Eressea PB(E)M host Copyright (C) 1998-2000
|
||||||
* Christian Schlittchen (corwin@amber.kn-bremen.de)
|
* Christian Schlittchen (corwin@amber.kn-bremen.de)
|
||||||
* Katja Zedel (katze@felidae.kn-bremen.de)
|
* Katja Zedel (katze@felidae.kn-bremen.de)
|
||||||
|
@ -41,7 +41,7 @@ vset_destroy(vset * s)
|
||||||
int
|
int
|
||||||
vset_erase(vset * s, void *item)
|
vset_erase(vset * s, void *item)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i != s->size; ++i)
|
for (i = 0; i != s->size; ++i)
|
||||||
if (s->data[i] == item) {
|
if (s->data[i] == item) {
|
||||||
|
@ -51,10 +51,11 @@ vset_erase(vset * s, void *item)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
vset_add(vset * s, void *item)
|
vset_add(vset * s, void *item)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
size_t i;
|
||||||
|
|
||||||
if (!s->data) {
|
if (!s->data) {
|
||||||
s->size = 0;
|
s->size = 0;
|
||||||
|
@ -72,3 +73,35 @@ vset_add(vset * s, void *item)
|
||||||
++s->size;
|
++s->size;
|
||||||
return s->size - 1;
|
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:
|
/* 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
|
* Eressea PB(E)M host Copyright (C) 1998-2000
|
||||||
* Christian Schlittchen (corwin@amber.kn-bremen.de)
|
* Christian Schlittchen (corwin@amber.kn-bremen.de)
|
||||||
* Katja Zedel (katze@felidae.kn-bremen.de)
|
* Katja Zedel (katze@felidae.kn-bremen.de)
|
||||||
|
@ -21,9 +21,12 @@ struct vset {
|
||||||
size_t size;
|
size_t size;
|
||||||
size_t maxsize;
|
size_t maxsize;
|
||||||
};
|
};
|
||||||
void vset_init(vset * s);
|
extern void vset_init(vset * s);
|
||||||
void vset_destroy(vset * s);
|
extern void vset_destroy(vset * s);
|
||||||
unsigned int vset_add(vset * s, void *);
|
extern unsigned int vset_add(vset * s, void *);
|
||||||
int vset_erase(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
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue