图的简单表示-算法学习笔记十七
2017-05-06 11:17
218 查看
基于邻接矩阵和邻接链表的图表示法,以及各自的深度优先遍历和广度优先遍历,但图的表示中没有加带权的边,只是简单写一写,学习一下,底层链表和队列用了通用链表
#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] = 4000 { {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 /********************************************/ /***************************************************************/
相关文章推荐
- 简单排序算法学习笔记-冒泡排序算法详解
- 数据结构与算法学习笔记——堆栈及其应用(10以内简单四则计算器)
- 两种简单算法 学习笔记
- Scala学习笔记:数组操作与简单算法示例
- C++学习笔记十七 - 简单的类型强制转换
- 数据结构学习笔记一:简单排序与查询算法
- OpenCV 2 学习笔记(8): 利用邻域处理图像与简单的算术图像处理算法:图像滤波与加权和
- 简单算法学习笔记一
- 深度学习笔记(二):简单神经网络,后向传播算法及实现
- php学习笔记(十七)简单的数据库操作链接
- 简单算法学习笔记二
- IOS学习笔记之十七:Category的简单理解和应用
- 【算法学习笔记】53.单调队列的简单应用 SJTU OJ 1034 二哥的金链
- 【学习笔记】简单寻路算法(低效率)
- cocos2d-x 菜鸟学习笔记十七(简单的碰撞检测 实践篇 下)
- MIT 6.00 1x Lecture 3 - Simple Algorithms 简单算法 学习笔记
- 【算法学习笔记】91.简单森林计数 SJTU OJ 1045 二哥的家族
- 特征提取算法简单学习笔记
- 操作系统学习笔记(9) 互斥和同步的信号量算法
- 算法(第四版)学习笔记之java实现希尔排序