本文主要是针对课本上所定义的图的两种标准结构进行图的实现,下一篇会主要介绍对于平时做题时的图的一种更为常见的实现。
邻接矩阵
common.h
// common.h
#ifndef common_H
#define common_H
/* 函数结果状态码 */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
//#define OVERFLOW -2
//#define UNDERFLOW -3
#define ILLEGAL '#'
/* 类型定义 */
typedef int Status; // Status是函数的类型,其值是函数结果状态码
typedef int ElemType; // ElemType是数据类型
#endif
MGraph.h
// MGraph.h
#ifndef MGraph_H
#define MGraph_H
#include <cstring>
#include "common.h"
#define MAXSIZE 16
#define UNDIRECTED
// 邻接矩阵存储结构声明
struct MGraph{
int vertex_num; // 节点数
int edge_num; // 边数
ElemType vertex[MAXSIZE]; // 顶点信息
int arc[MAXSIZE][MAXSIZE];// 边信息
MGraph(){ std::memset( this, 0, sizeof(MGraph) ); };
};
typedef Status (*callback)(MGraph&, int);
// 创建邻接矩阵
Status create_graph( MGraph& graph, ElemType* arr, int n, int e );
// 输出邻接矩阵
Status show_graph(MGraph& graph);
// 深度优先遍历
Status dfs_graph(MGraph& graph, int u, int* visited, callback visit ); // u是遍历起点序号
// 广度优先遍历
Status bfs_graph(MGraph& graph, int u, int* visited, callback visit); // u是遍历起点序号
#endif
MGraph.cpp
// MGraph.cpp
#include <iostream>
#include <fstream>
#include <queue>
#include "MGraph.h"
#define LOCAL // for test
// 创建邻接矩阵
Status create_graph( MGraph& graph, ElemType* arr, int n, int e ){
if( !arr || n <= 0 ){
std::cerr << "Invalid arguments!" << std::endl;
return ERROR;
}
graph.vertex_num = n;
graph.edge_num = e;
for( int i = 1; i <= graph.vertex_num; ++i){ // 顶点值从1开始,下标也从1开始
graph.vertex[i] = arr[i];
}
#ifdef LOCAL
std::ifstream cin( "input.dat" );
#endif
for( int i = 0; i < graph.edge_num; ++i ){
int u,v;
//std::cin >> u >> v;
cin >> u >> v;
graph.arc[u][v] = 1;
#ifdef UNDIRECTED
graph.arc[v][u] = 1;
#endif
}
#ifdef LOCAL
cin.close();
#endif
return OK;
}
// 输出邻接矩阵
Status show_graph(MGraph& graph){
for( int u = 1; u <= graph.vertex_num; ++u ){
for( int v = 1; v <= graph.vertex_num; ++v ){
std::cout << graph.arc[u][v] << " ";
}
std::cout << std::endl;
}
return OK;
}
// 深度优先遍历
Status dfs_graph(MGraph& graph, int u, int* visited, callback visit){
if(u < 1 || !visited || !visit){
std::cerr << "Invalid arguments!";
return ERROR;
}
visited[u] = 1;
visit(graph, u);
for( int v = 1; v <= graph.vertex_num; ++v ){
if( graph.arc[u][v] && !visited[v] )
dfs_graph( graph, v, visited, visit );
}
return OK;
}
// 广度优先遍历
Status bfs_graph(MGraph& graph, int u, int* visited, callback visit){
if(u < 1 || !visited || !visit){
std::cerr << "Invalid arguments!";
return ERROR;
}
std::queue<int> que;
visited[u] = 1;
visit(graph, u);
que.push(u);
while(!que.empty()){
u = que.front();
que.pop();
for( int v = 1; v <= graph.vertex_num; ++v ){
if( graph.arc[u][v] && !visited[v] ){
visited[v] = 1;
visit(graph, v);
que.push(v);
}
}
}
return OK;
}