/*
* =====================================================================================
*
* Filename: graph_matrix.c
*
* Description:
*
* Version: 1.0
* Created: 04/09/11 19:46:33
* Revision: none
* Compiler: gcc
*
* Author: chengenbao (chengenbao@ict.ac.cn)
* Company: Insititude of Computing Technology Chinese Academy of Siences
*
* =====================================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "graph_matrix.h"
#define MAX 100
typedef char node_type;
typedef unsigned char edge_type;
typedef struct
{
node_type node[MAX];
edge_type edge[MAX][MAX];
int node_num;
} graph;
int
find_node_index (graph *g, node_type value);
graph *
create_graph ();
void
read_graph (graph *g);
void
write (FILE *fp, graph *g);
int
find_neighbour (graph *g, int v, int start);
void
DFS (graph *g, int v, int *visited, FILE *fp, void (*output) (FILE *, node_type data));
void
DFS_traverse (graph *g, FILE *fp);
void
BFS (graph *g, int v, int *visited, FILE *fp, void (*output) (FILE *, node_type data));
void
BFS_traverse (graph *g, FILE *fp);
/*
* return a empty graph
*/
graph *
create_graph ()
{
graph *g;
int i, j;
g = (graph *) malloc (sizeof(graph));
if ( NULL == g)
{
fprintf (stderr, "No enough memory!/n");
exit (1);
}
g->node_num = 0;
// empty the edge
for ( i = 0; i < MAX; i++)
for ( j = 0; j< MAX; j++)
g->edge[i][j] = 0;
return g;
}
/*
* read a graph from user console
* g is a pointer point to the graph
* there must be some alloceted memory
* space for graph g
*
*/
void
read_graph (graph *g)
{
int node_num, edge_num;
int i;
int v0_index, v1_index;
FILE *input;
char filename[100];
node_type v0, v1;
if ( NULL == g)
{
g = create_graph ();
}
printf ("please input your choice:/n"
"1. read from file/n"
"2. read from console/n");
scanf ("%d", &i);
getchar ();
if ( i == 1)
{
printf ("please input file name/n");
scanf ("%s", filename);
getchar ();
input = fopen (filename, "r");
}
else
input = stdin;
if (input == stdin)
printf ("Please input number of node and edge, eg: 10 40/n");
fscanf (input, "%d%d", &node_num, &edge_num);
fgetc (input);
assert ( node_num >= 0 && edge_num >= 0);
if ( node_num > MAX)
{
fprintf (stderr, "You should not input more than %d nodes!/n");
exit (2);
}
g->node_num = node_num;
check_edge:
if ( edge_num > (node_num - 1) * node_num / 2)
{
if (input == stdin)
{
fprintf (stderr, "Illege edge number, please reinput!/n");
scanf ("%d", &edge_num);
getchar ();
goto check_edge;
}
else
{
fprintf (stderr, "Illege edge number, please reinput!/n");
exit (3);
}
}
if ( input == stdin)
printf ("Please input the nodes data(a charactor)!/n");
for ( i = 0; i < node_num; i++)
{
fscanf (input, "%c", &g->node[i]);
}
if (input == stdin)
printf ("Please input the edges, eg: a,b/n");
for ( i = 0; i < edge_num; i++)
{
fgetc(input);
fscanf (input, "%c,%c", &v0, &v1);
printf ("%c,%c/n", v0, v1);
v0_index = find_node_index (g, v0);
v1_index = find_node_index (g, v1);
g->edge[v0_index][v1_index] = g->edge[v1_index][v0_index] = 1;
}
}
/*
* find the node index according to the node value
* @param:g is the graph to search
* @param: value is the node value to be serached
* @return: if success, return the ndoe index (zero based)
* else return -1
*/
int
find_node_index (graph *g, node_type value)
{
int i;
for ( i = 0; i < g->node_num; i++)
if ( g->node[i] == value)
return i;
return -1;
}
/*
* output the graph information to file
* @param: fp is a pointer point to the output file
* @param: g is the graph to be outputed
*
*/
void
write (FILE *fp, graph *g)
{
int node_num, i, j;
node_num = g->node_num;
fprintf (fp, "node number: %d/n", node_num);
if ( node_num)
{
fprintf (fp, "All nodes: {");
for ( i = 0; i < node_num; i++)
fprintf (fp, "%c%c ", g->node[i], (i < node_num - 1)?',':'}');
fprintf (fp, "/n/n");
fprintf (fp, "---------------------------edges-------------------------/n");
fprintf (fp, " ");
for ( i = 0; i < node_num; i++)
fprintf (fp, "%2c", g->node[i]);
fprintf (fp, "/n");
for ( i = 0; i < node_num; i++)
{
fprintf (fp, "%2c", g->node[i]);
for ( j = 0; j < node_num; j++)
fprintf (fp, "%2d", g->edge[i][j]);
fprintf (fp, "/n");
}
}
}
void
output (FILE *fp, node_type data)
{
fprintf (fp, "%c ", data);
}
void
DFS_traverse (graph *g, FILE *fp)
{
int i, num, *visited;
num = g->node_num;
visited = (int *) malloc (sizeof (sizeof(int) * num));
for ( i = 0; i < num; i++)
visited[i] = 0;
fprintf (fp, "/n--------------------DFS traverse path-------------------/n");
for ( i = 0; i < num; i++)
{
if (!visited[i])
{
DFS(g, i, visited, fp, &output);
fprintf (fp, "/n");
}
}
}
void
DFS (graph *g, int v, int *visited, FILE *fp, void (*output) (FILE *, node_type data))
{
int stack[MAX];
int top;
int w;
top = 0; // init statck point
w = -1;
if ( !visited[v])
{
visited[v] = 1;
stack[top++] = v; //push v into stack
(*output) (fp, g->node[v]);
}
while (top) //stack not empty
{
for ( w = find_neighbour (g, v, w); w != -1; w = find_neighbour (g, v, w))
{
//printf ("(%d, %d)/n", v, w);
if ( !visited[w])
break;
}
if ( w == -1) // all of v's neighbour has been visted
{
w = v;
v = stack[--top]; //
}
else // w is a unvisited neighbour of v
{
visited[w] = 1;
stack[top++] = w;
(*output) (fp, g->node[w]);
v = w;
w = -1;
}
}
}
int
find_neighbour (graph *g, int v, int start)
{
int i;
//printf ("hello/n");
for ( i = start + 1; i < g->node_num; i++)
if (g->edge[v][i])
return i;
return -1;
}
int
main (int argc, char **argv)
{
graph *g;
FILE *fp;
g = NULL;
fp = fopen ("result.txt", "w");
g = create_graph();
read_graph (g);
write(fp, g);
DFS_traverse (g, fp);
fclose (fp);
system ("vim result.txt");
exit (0);
}
数据结构-图
最新推荐文章于 2023-02-08 16:19:50 发布