// 图.cpp : 定义控制台应用程序的入口点。
//邻接矩阵表示的无向图
#include "stdafx.h"
#include "malloc.h"
#define MaxVertexNum 100
typedef char VertexType;//顶点数据类型 目前定义为char类型
typedef int EdgeType; //带权图中边上权值的数据类型 目前定义为int类型
bool visited[MaxVertexNum];
typedef struct
{//邻接矩阵,适合稠密图
VertexType Vex[MaxVertexNum]; //顶点表 注意区分顶点号与顶点值
EdgeType Edge[MaxVertexNum][MaxVertexNum]; //邻接矩阵,边表 !!!注意是对称表
int vexnum,arcnum; //arc弧
}MGraph;
//
void CreateGraph(MGraph &G,VertexType* V,EdgeType* Edge,int vexnum)
{//用二维表建立一个矩阵
G.vexnum=vexnum;//顶点数
for (int i=0;i<G.vexnum;i++)
{
G.Vex[i]=V[i];
for (int j=0;j<G.vexnum;j++)
{
G.Edge[i][j]=Edge[i*vexnum+j];
if (Edge[i*vexnum+j]) //边数
G.arcnum++;
}
}
}
bool Adjacent(MGraph G,VertexType x,VertexType y)//判断顶点x,y中有无边 顶点标号 1,2,3,......
{
if (G.Edge[x-1][y-1])
return true;
else
return false;
}
void Neighbors(MGraph G,VertexType x)//列出图G中与结点x邻接的边
{
for (int i=1;i<=G.vexnum;i++)
{
if (Adjacent(G,x,i))
{
printf("%d ",i);
}
}
printf("\n");
}
void InsertVertex(MGraph &G,VertexType x)//在图G中插入顶点x
{
G.vexnum++;
G.Vex[G.vexnum-1]=x;//处理顶点结点
//处理边的关系
for (int i=0;i<G.vexnum;i++)
{
G.Edge[G.vexnum-1][i]=0;
}
for (int j=0;j<G.vexnum;j++)
{
G.Edge[j][G.vexnum-1]=0;
}
}
void DeleteVertex(MGraph &G,VertexType x)//图G中删除顶点x
{
;
for (int i=0;i<G.vexnum;i++)
{
if (G.Edge[x-1][i]==1)
{
G.arcnum--;//边的总数减一
}
G.Edge[x-1][i]=0;
}
for (int j=0;j<G.vexnum;j++)
{
if (G.Edge[j][x-1]==1)
{
G.arcnum--; //边的总数减一
}
G.Edge[j][x-1]=0;
}
G.vexnum--;
}
void DispGraph(MGraph G)
{//将边的连接情况表示出来
for (int i=0;i<G.vexnum;i++)
{
for (int j=0;j<G.vexnum;j++)
{
printf("%d ",G.Edge[i][j]);
}
printf("\n");
}
}
void AddEdge(MGraph &G,int x,int y)//如果边(x,y)或者<x,y>不存在,在图G中添加该边
{
if(G.Edge[x-1][y-1]==0)
{
G.arcnum++;
G.Edge[x-1][y-1]=1;
G.Edge[y-1][x-1]=1;
}
}
void RemoveEdge(MGraph &G,int x,int y)//如果边(x,y)或者<x,y>存在,在图G中删除该边
{
if(G.Edge[x-1][y-1]==1)
{
G.arcnum--;
G.Edge[x-1][y-1]=0;
G.Edge[y-1][x-1]=0;
}
}
int FirstNeighbor(MGraph G,int x)
{
for (int i=0;i<G.vexnum;i++)
{
if (G.Edge[x-1][i]==1)
{
return i+1;
}
}
return -1;//第一个邻接点不存在
}
int NextNeighbor(MGraph G,int x,int y)
{
for (int i=y;i<G.vexnum;i++)
{
if (G.Edge[x-1][i]==1)
{
return i+1;
}
}
return -1;//除y之外的顶点x的下一个邻接点不存在
}
EdgeType Get_edge_value(MGraph G,int x,int y)//获取(x,y)或者<x,y>对应的权值
{
return G.Edge[x-1][y-1];
}
void Set_edge_value(MGraph &G,int x,int y,EdgeType v)//设置(x,y)或者<x,y>对应的权值
{
G.Edge[x-1][y-1]=v;
}
队列操作/
typedef struct LinkNode//链式队列结点
{
int data;
struct LinkNode * next;
}LinkNode;
typedef struct// 链式队列
{
LinkNode *front,*rear;
}LiQueue;
void InitQueue(LiQueue &Q)
{
Q.front=Q.rear=(LinkNode*)malloc(sizeof(LinkNode));//建立头结点
Q.front->next=NULL;
}
bool QueueEmpty(LiQueue Q)
{
if (Q.rear==Q.front)
return true;
else
return false;
}
void EnQueue(LiQueue &Q,int x)
{
LinkNode *s=(LinkNode *)malloc(sizeof(LinkNode));
s->data=x; s->next=NULL;//创建新节点,插入到链尾
Q.rear->next=s;
Q.rear=s;
}
bool DeQueue(LiQueue &Q,int &x)
{//Q.front一直指向头结点
if (Q.front==Q.rear)//空队
return false;
LinkNode* p=Q.front->next;
x=p->data;
Q.front->next=p->next;
if (Q.rear==p)//若队列中只有一个结点,删除后变空
Q.rear=Q.front;
free(p);
return true;
}
void DispQueue(LiQueue Q)
{
if (QueueEmpty(Q))
return ;
LinkNode*p=Q.front->next;
while(p!=Q.rear)
{
printf("%d ",p->data);
p=p->next;
}
printf("%d \n",Q.rear->data);
}
/
void visit(MGraph G,int vertex)
{//访问顶点vertex
printf("%c ",G.Vex[vertex-1]);
}
void BFS(MGraph G,int i)
{//BFS第i个顶点
LiQueue Q;
InitQueue(Q);
visit(G,i);
visited[i-1]=true;
EnQueue(Q,i);//第i个顶点入队
int v;
while(!QueueEmpty(Q))
{
DeQueue(Q,v); //让第v+1个顶点入队
for (int w=FirstNeighbor(G,v)-1;w>=0;w=NextNeighbor(G,v,w+1)-1)
{
if (!visited[w])
{
visit(G,w+1);
visited[w]=true;
EnQueue(Q,w);//让第w+1个顶点进队
}
}
}
}
void BFSTraverse(MGraph G)//广度优先遍历
{
for (int i=0;i<G.vexnum;i++)
visited[i]=false;
for (int i=0;i<G.vexnum;i++)
{
if (!visited[i])
{
BFS(G,i+1); //第i+1个顶点从未被访问过,从Vi开始
}
}
}
void BFS_MIN_Distance(MGraph G,int u)//求顶点u到其他顶点的最短路径
{//d[i]表示顶点u到顶点i+1的最短路径
int d[MaxVertexNum];
for (int i=0;i<G.vexnum;i++)
{
visited[i]=false;
d[i]=10000;//表示无穷大,没有路径
}
visited[u-1]=true; d[u-1]=0;//自身距离为0
LiQueue Q;
InitQueue(Q);
EnQueue(Q,u);//第u个顶点入队
while(!QueueEmpty(Q))
{
int v;
DeQueue(Q,v);//让第v个顶点出队
for (int w=FirstNeighbor(G,v)-1;w>=0;w=NextNeighbor(G,v,w+1)-1)
{
if (!visited[w])
{
visited[w]=true;
d[w]=d[v-1]+1;
EnQueue(Q,w+1);//让第w+1个顶点入队;
}
}
}
for (int i=0;i<G.vexnum;i++)
{
printf("%d ",d[i]);
}
}
void DFS(MGraph G,int v)
{//深度优先搜索第v个顶点
visit(G,v);
visited[v-1]=true;//设已访问标记
for (int w=FirstNeighbor(G,v)-1;w>=0;w=NextNeighbor(G,v,w+1)-1)
{
if(!visited[w])
{
DFS(G,w+1);
}
}
}
void DFSTraverse(MGraph G)
{
for (int i=0;i<G.vexnum;i++)
visited[i]=false;
for (int i=0;i<G.vexnum;i++)
{
if (!visited[i])
{
DFS(G,i+1); //第i+1个顶点从未被访问过,从Vi开始
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{//学会从编译器的角度去编程
MGraph G;
VertexType V[]={'a','b','c','d','e','f','g','h'};
EdgeType Edge[]=
{
0,1,1,0,0,0,0,0,
1,0,0,1,1,0,0,0,
1,0,0,0,0,1,1,0,
0,1,0,0,0,0,0,0,
0,1,0,0,0,0,0,1,
0,0,1,0,0,0,0,0,
0,0,1,0,0,0,0,0,
0,0,0,0,1,0,0,0
};
CreateGraph(G,V,Edge,8);
DispGraph(G);
//
BFSTraverse(G);//深度优先遍历
printf("\n");
//
BFS_MIN_Distance(G,2);//求第2个顶点到其他顶点的最短距离;
printf("\n");
//
DFSTraverse(G);
printf("\n");
return 0;
}