数据结构-图

本文介绍了一个使用 C 语言实现的图数据结构及其基本操作,包括创建空图、从文件或控制台读取图、将图写入文件等。此外,还详细介绍了深度优先搜索(DFS)和广度优先搜索(BFS)两种图遍历算法,并提供了完整的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


/*
 * =====================================================================================
 *
 *       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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值