图的深度优先搜索和广度优先搜索



// 图.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;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值