图的简单表示-算法学习笔记十七

基于邻接矩阵和邻接链表的图表示法,以及各自的深度优先遍历和广度优先遍历,但图的表示中没有加带权的边,只是简单写一写,学习一下,底层链表和队列用了通用链表


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define PRINT(format, arg...) \
do{ \
    printf("[%s/%d]:", __func__, __LINE__); \
    printf(format, ##arg); \
    printf("\n"); \
}while(0)

/*****************************图********************************/

#define MAX_VERTEX_NUM 100

typedef struct init_array {
    int start_v;
    int end_v;
} init_array;

/**************邻接矩阵表示****************/
typedef struct matrix_graph {
    int vertex[MAX_VERTEX_NUM];  // 存放顶点信息
    int v_num;  // 顶点数
    int e_num;  // 边数
    int matrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
} matrix_graph;

matrix_graph *init_matrix_graph(
    int v_num,
    int e_num )
{
    int i = 0, j = 0;
    matrix_graph *graph = NULL;

    graph = ( matrix_graph * )malloc( sizeof(matrix_graph) );
    graph->v_num = v_num;
    graph->e_num = e_num;

    for ( i = 0; i < MAX_VERTEX_NUM; i++ ) {
        if ( i < v_num )
            graph->vertex[i] = i;
        else
            graph->vertex[i] = -1;

        for ( j = 0; j < MAX_VERTEX_NUM; j++ ) {
            graph->matrix[i][j] = 0;
        }
    }

    return graph;
}
matrix_graph *create_matrix_graph(
    init_array *i_arr,
    int arr_size,
    int v_num )
{
    int i = 0;
    matrix_graph *graph = NULL;

    graph = init_matrix_graph( v_num, arr_size );

    for ( i = 0; i < arr_size; i++ ) {
        graph->matrix[i_arr[i].start_v][i_arr[i].end_v] = 1;
    }

    return graph;
}
int visited[MAX_VERTEX_NUM] = {0};
// 深度优先遍历
void dfs_matrix_graph1(
    matrix_graph *g,
    int v )
{
    visited[v] = 1;
    printf("%d ", v);

    // 搜索此结点的下一个结点
    int i = 0;
    for ( i; i < g->v_num; i++ ) {
        if ( g->matrix[v][i] && !visited[i] )
            dfs_matrix_graph1( g, i );
    }
}
void dfs_matrix_graph(
    matrix_graph *g )
{
    int i = 0;

    for ( i; i < g->v_num; i++ )
        visited[i] = 0;

    printf("deep first visit:\n\t");

    for ( i = 0; i < g->v_num; i++ ) {
        if ( !visited[i] )
            dfs_matrix_graph1( g, i );
    }
    printf("\n");
}
// 广度优先搜索
void bfs_matrix_graph(
    matrix_graph *g )
{
    int i = 0;
    // 栈结点数据域,需要void *
    int tmp_vertex[MAX_VERTEX_NUM] = {0};
    queue *q = create_queue();

    for ( i = 0; i < g->v_num; i++ )
        visited[i] = 0;

    printf("broad first visit:\n\t");

    for ( i = 0; i < g->v_num; i++ ) {
        if ( !visited[i] ) {
            tmp_vertex[i] = i;
            q->enqueue(q->this, &tmp_vertex[i]);

            while ( q->size(q->this) != 0 ) {
                int tmp = *( int * )q->dequeue( q->this );
                if ( !visited[tmp] )
                    printf("%d ", tmp);

                visited[tmp] = 1;

                int j = 0;
                for ( j = 0; j < g->v_num; j++ ) {
                    if ( g->matrix[tmp][j] && !visited[j] ) {
                        tmp_vertex[j] = j;
                        q->enqueue( q->this, &tmp_vertex[j] );
                    }
                }
            }
        }
    }

    q->free( q->this );
    printf("\n");
}
void free_matrix_graph(
    matrix_graph *g )
{
    free( g );
}
#undef DEBUG_MATRIX_GRAPH
#ifdef DEBUG_MATRIX_GRAPH

int main()
{
    init_array i_arr[20] =
        {
            {0, 4},
            {0, 9},
            {1, 5},
            {2, 1},
            {2, 6},
            {3, 2},
            {3, 6},
            {4, 7},
            {4, 8},
            {5, 2},
            {6, 5},
            {7, 6},
            {7, 3},
            {8, 7},
            {8, 4},
            {9, 8},
        };

    matrix_graph *g = create_matrix_graph( i_arr, 16, 10 );

    dfs_matrix_graph( g );

    bfs_matrix_graph( g );

    free_matrix_graph( g );
}

#endif
/********************************************/

/**************图的邻接链表*******************/
typedef struct link_list_graph {
    int vertex[MAX_VERTEX_NUM];
    int v_num;
    int e_num;
    link_list v_list[MAX_VERTEX_NUM];
} link_list_graph;

// 链表数据域,需要void *
int tmp_vertex[MAX_VERTEX_NUM] = {0};

link_list_graph *create_link_list_graph(
    init_array *i_arr,
    int arr_size,
    int v_num )
{
    int i = 0;
    link_list_graph *graph = NULL;

    graph = ( link_list_graph * )malloc( sizeof(link_list_graph) );
    graph->e_num = arr_size;
    graph->v_num = v_num;
    for ( i = 0; i < v_num; i++ ) {
        tmp_vertex[i] = i;

        //定制链表操作
        graph->v_list[i].size = 0;
        graph->v_list[i].insert = insert_tail;
        graph->v_list[i].get_first = get_head;
        graph->v_list[i].get_last = get_tail;
        graph->v_list[i].del = del_tail;
        graph->v_list[i].insert( &graph->v_list[i], &tmp_vertex[i]);
    }

    for ( i = 0; i < arr_size; i++ ) {
        int start = i_arr[i].start_v;
        int end = i_arr[i].end_v;
        graph->v_list[start].insert( &graph->v_list[start], &tmp_vertex[end]);
        printf("start:%d->end:%d, size:%d\n", start, end, graph->v_list[start].size);
    }

    return graph;
}
void dfs_link_list_graph1(
    link_list_graph *g,
    int v )
{
    link_list_node *p = g->v_list[v].head;

    if ( !visited[*(int *)(p->data)] ) {
        printf("%d ", *(int *)(p->data));
        visited[v] = 1;
        while ( 1 ) {
            p = p->next;
            if ( p == g->v_list[v].head )
                break;
            if ( !visited[*(int *)(p->data)] ) {
                dfs_link_list_graph1( g, *(int *)(p->data) );
            }
        }
    }
}
void dfs_link_list_graph(
    link_list_graph *g )
{
    int i = 0;

    printf("深度优先遍历:\n\t");
    for ( i = 0; i < g->v_num; i++ )
        visited[i] = 0;

    for ( i = 0; i < g->v_num; i++ ) {
        if ( g->v_list[i].size > 0 && !visited[i] )
            dfs_link_list_graph1( g, i );
    }
    printf("\n");
}
void bfs_link_list_graph(
    link_list_graph *g )
{
    int i = 0;
    // 栈结点数据域,需要void *
    int tmp_vertex[MAX_VERTEX_NUM] = {0};
    queue *q = create_queue();

    for ( i = 0; i < g->v_num; i++ ){
        tmp_vertex[i] = i;
        visited[i] = 0;
    }

    printf("广度优先遍历:\n\t");

    for ( i = 0; i < g->v_num; i++ ) {
        if ( !visited[i] ) {
            tmp_vertex[i] = i;
            q->enqueue(q->this, &tmp_vertex[i]);

            while ( q->size(q->this) != 0 ) {
                int tmp = *( int * )q->dequeue( q->this );
                if ( !visited[tmp] )
                    printf("%d ", tmp);

                visited[tmp] = 1;

                int j = 0;
                link_list_node *p = g->v_list[tmp].head->next;

                while ( p != g->v_list[tmp].head ) {
                    if ( !visited[*(int *)p->data] ) {
                        q->enqueue( q->this, &tmp_vertex[*(int *)p->data] );
                    }
                    p = p->next;
                }
            }
        }
    }
    q->free( q->this );
    printf("\n");
}
void free_link_list_graph(
    link_list_graph *g )
{
    int i = 0;

    for ( i = 0; i < g->v_num; ++i ) {
        del_list( &g->v_list[i] );
    }
    free( g );
}
#define DEBUG_LINK_LIST_GRAPH
#ifdef DEBUG_LINK_LIST_GRAPH

int main()
{
    init_array i_arr[20] =
        {
            {0, 4},
            {0, 9},
            {1, 5},
            {2, 1},
            {2, 6},
            {3, 2},
            {3, 6},
            {4, 7},
            {4, 8},
            {5, 2},
            {6, 5},
            {7, 6},
            {7, 3},
            {8, 7},
            {8, 4},
            {9, 8},
        };

    link_list_graph *g = create_link_list_graph( i_arr, 16, 10 );

    dfs_link_list_graph( g );

    bfs_link_list_graph( g );

    free_link_list_graph( g );
}

#endif

/********************************************/


/***************************************************************/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值