/* * ===================================================================================== * * 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 100typedef char node_type;typedef unsigned char edge_type;typedef struct{ node_type node[MAX]; edge_type edge[MAX][MAX]; int node_num;} graph;intfind_node_index (graph *g, node_type value);graph *create_graph ();voidread_graph (graph *g);voidwrite (FILE *fp, graph *g);intfind_neighbour (graph *g, int v, int start);voidDFS (graph *g, int v, int *visited, FILE *fp, void (*output) (FILE *, node_type data));voidDFS_traverse (graph *g, FILE *fp);voidBFS (graph *g, int v, int *visited, FILE *fp, void (*output) (FILE *, node_type data));voidBFS_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 * */voidread_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 */intfind_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 * */voidwrite (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"); } }}voidoutput (FILE *fp, node_type data){ fprintf (fp, "%c ", data);}voidDFS_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"); } }}voidDFS (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; } }}intfind_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;}intmain (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);}