数据结构-图

来源:互联网 发布:vb向上取整函数 编辑:程序博客网 时间:2024/04/28 17:17
/* * ===================================================================================== * *       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);}
原创粉丝点击