实现图的存储结构;
实现图的深度优先和广度优先遍历
/****************************************************
@Title: 数据结构实验
@Name: <实验7-1> 图的遍历
@Object:
[实验目的]
实现图的存储结构;
实现图的深度优先和广度优先遍历
[实验提示]
1. 在 graph.h 中实现图的基本操作
2. 在 graph.h 中实现图的深度优先遍历和广度
优先遍历
@Include:
ds.h
类C通用模块
graph.h [*]
图的实现
@Usage:
请查看"TO-DO列表",根据要求完成代码
@Copyright: BTC 2004, Zhuang Bo
@Author: Zhuang Bo
@Date: 2004
@Description:
*****************************************************/
#include <stdio.h>
#include <stdlib.h> //for system()
#include "ds.h"
#include "graph.h"
Status printvex(VexType val); //访问顶点的函数
void main()
{
MGraph g;
//建立图
CreateGraph(g);
//printf("\n邻接矩阵:\n");
PrintAdjMatrix(g); //打印邻接矩阵
//深度优先和广度优先遍历图
printf("\n深度优先遍历:\n");
DFSTraverse(g,0,printvex); //从顶点0开始
printf("\n广度优先遍历:\n");
BFSTraverse(g,0,printvex);
//销毁图
DestroyGraph(g);
system("pause"); //暂停
}
//打印顶点
Status printvex(VexType val)
{
write(val);
return OK;
}
/*
Name: 图的邻接矩阵存储结构
Copyright: BTC 2004
Author: Zhuang Bo
Date: 2004
Description:
*/
#ifndef GRAPH_H_INCLUDED
#define GRAPH_H_INCLUDED
#include <stdio.h>
#include "ds.h"
///////////////////////////////////////////////////////////
//图的邻接矩阵表示
#define MAX_VERTEX_NUM 20 //最大顶点数
#define VexType char //顶点类型
#define ArcType int
#define INFINITY INT_MAX //无穷大
typedef struct {
VexType vexs[MAX_VERTEX_NUM]; //顶点向量
ArcType arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //邻接矩阵
int vexnum,arcnum; //顶点,边个数
} MGraph;
///////////////////////////////////////////////////////////
//图的基本操作声明
//输入顶点和弧的信息,建立图
Status CreateGraph(MGraph &G);
//销毁图的结构
Status DestroyGraph(MGraph &G);
//取顶点
VexType GetVex(MGraph G, int v);
//更新顶点信息
Status PutVex(MGraph &G, int v, VexType val);
//插入弧(v,w)
Status InsertArc(MGraph &G, int v, int w, ArcType arc);
//删除弧(v,w)
Status DeleteArc(MGraph &G, int v, int w);
//插入顶点v
Status InsertVex(MGraph &G, VexType val);
//删除顶点v
Status DeleteVex(MGraph &G, int v);
//图G中顶点v的第一个邻接点
int FirstAdjVex(MGraph G, int v);
//图G中顶点v在w之后的下一个邻接点
int NextAdjVex(MGraph G, int v, int w);
//深度优先遍历图
Status DFSTraverse(MGraph G, int v, Status(*Visit)(VexType));
//广度优先遍历图
Status BFSTraverse(MGraph G, int v, Status(*Visit)(VexType));
//打印邻接矩阵(调试用)
void PrintAdjMatrix(MGraph G);
int locateVex(MGraph G, VexType v);
///////////////////////////////////////////////////////////
//基本操作的实现
int locateVex(MGraph G, VexType v){
for(int i = 0; i < G.vexnum; i++){
if(G.vexs[i] == v)
return i;
}
return -1;//图中没有该顶点
}
//输入顶点和弧的信息,建立图
Status CreateGraph(MGraph &G)
{
//-------------------------------------
// TODO (#1#): 先输入顶点个数和顶点数据,然后输入弧,建立图
printf("输入顶点数和弧数如:(5,3):");
scanf("%d,%d", &G.vexnum, &G.arcnum);
printf("输入%d个顶点(以空格隔开如:v1 v2 v3):", G.vexnum);
getchar();//吃掉换行符
for(int m = 0; m < G.vexnum; m++){
scanf("%c", &G.vexs[m]);
getchar();//吃掉空格符
}
for( m = 0; m < G.vexnum; m++){
printf("%c", G.vexs[m]);
printf("\n");
// getchar();//吃掉空格符
}
//初始化邻接矩阵
int i=0, j=0;
for(i = 0; i < G.vexnum; i++){
for(j = 0; j < G.vexnum; j++)
G.arcs[i][j] = 0;
}
//打印初始化的邻接矩阵
/* for(i = 0; i < G.vexnum; i++){
for(j = 0; j < G.vexnum; j++)
printf( "%5d\n",G.arcs[i][j]);
}*/
VexType v1, v2;//分别是一条弧的弧尾和弧头(起点和终点)
int w;//对于无权图或网,用0或1表示相邻否;对于带权图或网,则为相应权值
printf("\n每行输入一条弧依附的顶点(先弧尾后弧头)和权值(如:v1 v2 3):\n");
fflush(stdin);//清除残余后,后面再读入时不会出错
for(int k = 0; k < G.arcnum; k++){
scanf("%c %c %d",&v1, &v2, &w);
fflush(stdin);//清除残余后,后面再读入时不会出错
i = locateVex(G, v1);
j = locateVex(G, v2);
G.arcs[i][j] = w;
}
return OK;
//-------------------------------------
}
//销毁图的结构
Status DestroyGraph(MGraph &G)
{
return OK;//什么也不做
}
//取顶点
Status GetVex(MGraph G, int v, VexType &val)
{
if(v<0||v>=G.vexnum) return ERROR;
val = G.vexs[v];
return OK;
}
//更新顶点信息
Status PutVex(MGraph &G, int v, VexType val)
{
if(v<0||v>=G.vexnum) return ERROR;
G.vexs[v] = val;
return OK;
}
//插入弧(v,w)
Status InsertArc(MGraph &G, int v, int w, ArcType arc)
{
if(v<0||v>=G.vexnum||w<0||w>=G.vexnum) return ERROR;
G.arcs[v][w] = arc;
return OK;
}
//删除弧(v,w)
Status DeleteArc(MGraph &G, int v, int w)
{
if(v<0||v>=G.vexnum||w<0||w>=G.vexnum) return ERROR;
G.arcs[v][w] = 0; //删除弧
return OK;
}
//插入顶点v
Status InsertVex(MGraph &G, VexType val)
{
//-------------------------------------
// TODO (#1#): 插入顶点v,注意对邻接矩阵的影响
return ERROR;
//-------------------------------------
}
//删除顶点v
Status DeleteVex(MGraph &G, int v)
{
//-------------------------------------
// TODO (#1#): 删除顶点v,注意对邻接矩阵的修改
return ERROR;
//-------------------------------------
}
//图G中顶点v的第一个邻接点,不存在时返回 -1
int FirstAdjVex(MGraph G, int v)
{
//-------------------------------------
// TODO (#1#): 返回顶点v的第一个邻接点
return -1;
//-------------------------------------
}
//图G中顶点v在w之后的下一个邻接点,不存在时返回 -1
int NextAdjVex(MGraph G, int v, int w)
{
//-------------------------------------
// TODO (#1#): 返回顶点v在w之后的下一个邻接点
return -1;
//-------------------------------------
}
//深度优先遍历图
Status DFSTraverse(MGraph G, int v, Status(*Visit)(VexType))
{
//-------------------------------------
// TODO (#1#): 从v出发,深度优先遍历图
return -1;
//-------------------------------------
}
//广度优先遍历图
Status BFSTraverse(MGraph G, int v, Status(*Visit)(VexType))
{
//-------------------------------------
// TODO (#1#): 从v出发,广度优先遍历图
return -1;
//-------------------------------------
}
//打印邻接矩阵
void PrintAdjMatrix(MGraph G)
{
int i,j;
for(i=0; i<G.vexnum; i++) {
write(G.vexs[i]);
for(j=0; j<G.vexnum; j++)
printf("%5d", G.arcs[i][j]);
printf("\n");
}
}
#endif //GRAPH_H_INCLUDED
/*
Name: 类C通用模块
Copyright: BTC 2004
Author: Zhuang Bo
Date: 2004
Description:
[Constants]
TRUE/FALSE/OK/ERROR/INFEASIBLE/OVERFLOW
[Types]
Status
[Functions]
max(a,b)
min(a,b)
read(char/int/float/double/char*)
write(char/int/float/double/char*)
*/
#ifndef _DS_H_
#define _DS_H_
// 函数结果状态代码
const int TRUE = 1;st int FALSE = 0;
const int OK = 1;
const int ERROR = 0;
const int INFEASIBLE = -1;
const int OVERFLOW = -2;
// Status 是函数的类型,其值是函数结果状态代码
typedef int Status;
//基本函数
#define max(a,b) (((a)<(b))?(b):(a))
#define min(a,b) (((a)<(b))?(a):(b))
#include <stdio.h>
//不用格式串的输入输出(目的是为了方便书写算法)
// 比如输入一个基本类型(char, int, float, double, char*)的
// 变量 x,可以直接用 read(x);输入,而打印则用 write(x);。
// 对于自定义类型,可以继续扩充。
inline void read(char& e) { e = getchar(); }
inline void read(int& e) { scanf("%d", &e); }
inline void read(float& e) { scanf("%f", &e); }
inline void read(double& e) { scanf("%lf", &e); }
inline void read(char *e) { gets(e); }
inline void write(char e) { printf("%c", e); }
inline void write(int e) { printf("%d", e); }
inline void write(float e) { printf("%f", e); }
inline void write(double e) { printf("%lf", e); }
inline void write(char *e) { printf("%s",e); }
#endif // _DS_H_