// Graph.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "stdio.h"
#include "iostream"
#include "stack"
#include "vector"
const int INFINITY = 9999;
const int MAX_VERTEX_NUM = 20;
const int ERROR = -1;
using namespace std;
typedef enum{
DG, // 有向图
DN, // 有向网
UDG, // 无向图
UDN // 无向网
}GraphKind;
typedef char VertexData;
typedef struct ArcNode
{
int Value; // 邻接矩阵,通过数量表示两个顶点之间是否相连
char * info; // 其他信息
}ArcNode, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 邻接矩阵中的元素
typedef struct ArcNode_AdjList
{
int adjvex; // 邻接点的索引
struct ArcNode_AdjList *nextarc;
char* info;
}ArcNode_AdjList;
typedef struct VertexNode
{
VertexData data;
int inDegree; // 顶点的入读
ArcNode_AdjList * firstArc; // 记录头结点
};
typedef struct
{
VertexNode vertexList[MAX_VERTEX_NUM]; // 各个图结点的邻接表
int vexnum;
int arcnum;
GraphKind kind;
}ALGraph;
typedef struct MGraph
{
VertexData vertex[MAX_VERTEX_NUM]; // 记录顶点数组
AdjMatrix arcs; // 邻接矩阵,是一个结构体的二维数组,结构体用来存储每一个边的信息
int vexnum; // 顶点的数量
int arcnum; // 边的数量
GraphKind kind;
}MGraph;
int LocateVertex(MGraph *G, VertexData v);
int CreateGraph(MGraph &G);
int CreateUDN(MGraph &G);
int CreateUDG(MGraph &G);
int CreateDN(MGraph &G);
int CreateDG(MGraph &G);
int CreateALGraph(ALGraph &ALG);
void FindInDegree(ALGraph &G, int indegree[]);
int TopoSort(ALGraph &G);
int TopoSortDFS(ALGraph &G);
void DFS(ALGraph &G, int indegree[]);
int _tmain(int argc, _TCHAR* argv[])
{
// 创建邻接矩阵图
/*MGraph graph;
CreateGraph(graph);
for (int i = 0; i < graph.vexnum;i++)
{
for (int j=0;j<graph.vexnum;j++)
{
printf("%5d",graph.arcs[i][j].Value);
}
printf("\n");
}*/
// 创建邻接表图
ALGraph G;
CreateALGraph(G);
for(int i = 0; i<G.vexnum; i++)
{
printf("node:%c",G.vertexList[i].data);
// 打印邻接表
ArcNode_AdjList *p = G.vertexList[i].firstArc;
while(p!=NULL)
{
printf("%d", p->adjvex);
p=p->nextarc;
}
printf("\n");
}
printf("Topo Sort ***************\n");
TopoSort(G);
// 遍历所有的可能的拓扑排序的结果
//TopoSortDFS(G);
printf("\n");
system("pause");
return 0;
}
int CreateGraph(MGraph &G)
{
printf("pls input the kind of the Graph! \n");
scanf("%d",&G.kind);
switch(G.kind)
{
case DG:return CreateDG(G);
case DN:return CreateDN(G);
case UDG:return CreateUDG(G);
case UDN:return CreateUDN(G);
default: return 0;
}
}
// 定位顶点的位置
int LocateVertex(MGraph *G, VertexData v)
{
int j = ERROR;
int k = 0;
for (k=0; k < G->vexnum; k++)
{
if (G->vertex[k] == v)
{
j = k;
break;
}
}
return j;
}
int CreateDG(MGraph &G)
{
//
return 0;
}
int CreateDN(MGraph &G)
{
//
int i,j,weight;
VertexData v1,v2;
printf("pls input arc num, vex num ('%%d,%%d')\n");
scanf("%d,%d",&G.arcnum,&G.vexnum);
fflush(stdin);
// 初始化邻接矩阵
for (int i = 0; i < G.vexnum; i++)
{
for (int j = 0; j < G.vexnum; j++)
{
G.arcs[i][j].Value = INFINITY;
}
}
// 输入图的顶点
printf("input graph vertex\n");
fflush(stdin);
for (int i = 0; i < G.vexnum; i++)
{
scanf("%c",&G.vertex[i]);
}
// 输入图的边
fflush(stdin);
printf("input graph edges %%c,%%c,%%d\n");
for (int k = 0; k<G.arcnum; k++)
{
scanf("%c,%c,%d",&v1,&v2,&weight);
i = LocateVertex(&G,v1);
j = LocateVertex(&G,v2);
G.arcs[i][j].Value = weight;
fflush(stdin);
}
return 1;
}
int CreateUDG(MGraph &G)
{
return 0;
}
int CreateUDN(MGraph &G)
{
//
return 0;
}
// 创建有向图的邻接表
int CreateALGraph(ALGraph &ALG)
{
ArcNode_AdjList *p;
int i,s,d;
ALG.kind = DN;
printf("pls input vertex num and edge num\n");
scanf("%d,%d",&s,&d);
ALG.vexnum = s;
ALG.arcnum = d;
fflush(stdin);
// 邻接表顶点初始化
for (i=0; i<ALG.vexnum;i++)
{
printf("第%d个顶点信息:\n",i+1);
scanf("%c", &ALG.vertexList[i].data);
ALG.vertexList[i].firstArc = NULL;
ALG.vertexList[i].inDegree = 0;
fflush(stdin);
}
// 每条边的信息初始化
for (i = 0; i<ALG.arcnum;i++)
{
printf("第%d条边的起始顶点编号与终止顶点编号:\n",i+1);
scanf("%d,%d",&s,&d);
while(s<1||s>ALG.vexnum||d<1||d>ALG.vexnum)
{
printf("顶点编号超出范围,重新输入\n");
scanf("%d,%d",&s,&d);
}
s--;
d--;
p = (ArcNode_AdjList*)malloc(sizeof(ArcNode_AdjList));
p->adjvex = d;
p->nextarc = ALG.vertexList[s].firstArc;
ALG.vertexList[s].firstArc = p;
ALG.vertexList[d].inDegree++;
fflush(stdin);
}
return 1;
}
// 深度优先遍历,获取所有可能的拓扑排序结果
stack<int> S;
vector<int> V;
int TopoSortDFS(ALGraph &G)
{
int indegree[MAX_VERTEX_NUM];
int i, count, k;
ArcNode_AdjList *p;
FindInDegree(G, indegree);
// 将入度为0的顶点入栈,即为拓扑排序中可以输出的顶点
for (i=0;i<G.vexnum;i++)
{
if (indegree[i]==0)
{
S.push(i);
V.push_back(i); // 保存到vector中
}
}
// TODO
DFS(G,indegree);
return 1;
}
void DFS(ALGraph &G, int indegree[])
{
if (V.size()==G.vexnum)
{
// 一次拓扑排序结束
printf("\n");
}
else
{
for (int i=0;i<V.size();i++)
{
int t = V[i];
printf("%c",G.vertexList[t].data);
//V.erase(V.begin()+i);
ArcNode_AdjList *p = G.vertexList[t].firstArc;
while(p!=NULL)
{
int k = p->adjvex;
indegree[k]--;
if (indegree[k]==0)
{
V.push_back(k);
}
p=p->nextarc;
}
DFS(G,indegree);
//V.insert(V.begin()+i,t);
p = G.vertexList[t].firstArc;
while(p!=NULL)
{
int k = p->adjvex;
indegree[k]++;
if (indegree[k]==0)
{
V.pop_back();
}
p=p->nextarc;
}
}
}
}
// 查找所有的可能存在的拓扑排序结果,深度优先遍历
// 拓扑排序
int TopoSort(ALGraph &G)
{
stack<int> S;
int indegree[MAX_VERTEX_NUM];
int i, count, k;
ArcNode_AdjList *p;
FindInDegree(G, indegree);
// 将入度为0的顶点入栈,即为拓扑排序中可以输出的顶点
for (i=0;i<G.vexnum;i++)
{
if (indegree[i]==0)
{
S.push(i);
}
}
count = 0;
while(!S.empty())
{
i = S.top();
S.pop();
printf("%c",G.vertexList[i].data); // 输出拓扑排序结果
count++;
p=G.vertexList[i].firstArc;
while(p!=NULL)
{
k = p->adjvex;
indegree[k]--;
if (indegree[k]==0)
{
S.push(k);
}
p=p->nextarc;
}
}
if (count<G.vexnum)
{
printf("网中有环,拓扑排序出错");
return -1;
}
return 1;
}
// 查找所有的顶点的入度
void FindInDegree(ALGraph &G, int indegree[])
{
int i,count,k;
for (i=0;i<G.vexnum;i++)
{
indegree[i] = 0;
}
for (i=0;i<G.vexnum;i++)
{
ArcNode_AdjList *p=G.vertexList[i].firstArc;
while(p!=NULL)
{
indegree[p->adjvex]++;
p=p->nextarc;
}
}
}
图的存储与拓扑排序
最新推荐文章于 2024-06-03 23:14:10 发布