Files
Data-Structure/Dev-C++/ExerciseBook/07.25/Graph.cpp
2020-02-18 03:44:06 +08:00

165 lines
3.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*=================================
* 由题7.25的描述创建的一种有向图结构
==================================*/
#include "Graph.h"
// 录入数据的源文件fp为null时说明需要从控制台录入
static FILE* fp = NULL;
/*
* 创建有向图
*
* path为NULL或为""时,从控制台读取图的初始化信息。
* 否则,从预设的文件中读取图的初始化信息。
*/
Status CreateGraph(Graph* G, char* path) {
int readFromConsole; // 是否从控制台读取数据
// 如果没有文件路径信息,则从控制台读取输入
readFromConsole = path == NULL || strcmp(path, "") == 0;
// 需要从文件读取
if(!readFromConsole) {
// 打开文件,准备读取测试数据
fp = fopen(path, "r");
if(fp == NULL) {
return ERROR;
}
}
Create(G);
if(fp != NULL) {
fclose(fp);
fp = NULL;
}
return OK;
}
/*
* 创建有向图的核心算法
*/
static void Create(Graph* G) {
int i, j, k;
VertexType v1, v2;
Boolean adjs[MAX_VERTEX_NUM][MAX_VERTEX_NUM] = {FALSE}; // 记录邻接点信息
int cur;
// 从控制台读取
if(fp == NULL) {
printf("请输入有向图的顶点数:");
scanf("%d", &((*G).vexnum));
printf("请输入有向图的弧数:");
scanf("%d", &((*G).arcnum));
// 录入顶点集
printf("请录入 %d 个顶点,不同顶点之间用空格隔开:", (*G).vexnum);
for(i = 0; i < (*G).vexnum; i++) {
// 跳过空白,寻找下一个"可读"符号
skipBlank(stdin);
scanf("%c", &((*G).vexs[i]));
}
// 从文件读取
} else {
ReadData(fp, "%d", &((*G).vexnum)); // 录入顶点数
ReadData(fp, "%d", &((*G).arcnum)); // 录入弧数
// 录入顶点集
for(i = 0; i < (*G).vexnum; i++) {
// 跳过空白,寻找下一个"可读"符号
skipBlank(fp);
ReadData(fp, "%c", &((*G).vexs[i]));
}
}
// 仅在控制台录入信息时输出此提示
if(fp == NULL && (*G).arcnum != 0) {
printf("请为有向图依次录入 %d 条弧的信息,顶点之间用空格隔开:\n", (*G).arcnum);
}
// 录入弧的信息
for(k = 0; k < (*G).arcnum; k++) {
if(fp == NULL) {
printf("第 %2d 条弧:", k + 1);
skipBlank(stdin); // 跳过空白,寻找下一个可读符号
scanf("%c", &v1);
skipBlank(stdin); // 跳过空白,寻找下一个可读符号
scanf("%c", &v2);
} else {
// 跳过空白,寻找下一个可读符号
skipBlank(fp);
ReadData(fp, "%c%c", &v1, &v2);
}
i = LocateVex(*G, v1); // 获取顶点v1在顶点集中的位置
j = LocateVex(*G, v2); // 获取顶点v2在顶点集中的位置
adjs[i][j] = TRUE;
}
cur = 0;
// 记录邻接点信息
for(i = 0; i < G->vexnum; i++) {
G->fst[i] = -1;
G->lst[i] = -2;
for(j = 0; j < G->vexnum; j++) {
if(adjs[i][j] == TRUE) {
if(G->fst[i] == -1) {
G->fst[i] = cur;
}
G->s[cur++] = j; // 存储后继顶点信息
}
}
if(G->fst[i] != -1) {
G->lst[i] = cur - 1;
}
}
}
/*
* 查找
*
* 返回顶点u在有向图中的位置
*/
int LocateVex(Graph G, VertexType u) {
int i;
for(i = 0; i < G.vexnum; i++) {
if(G.vexs[i] == u) {
return i;
}
}
return -1;
}
/*
* 打印有向图结构
*/
void PrintGraph(Graph G) {
int i, j;
if(G.vexnum == 0) {
printf("空图,无需打印!\n");
return;
}
printf("当前有向图包含 %2d 个顶点, %2d 条弧...\n", G.vexnum, G.arcnum);
for(i = 0; i < G.vexnum; i++) {
printf("%c -> ", G.vexs[i]);
for(j = G.fst[i]; j <= G.lst[i]; j++) {
printf("%c ", G.vexs[G.s[j]]);
}
printf("\n");
}
}