/*
#include <iostream>
#define maxn 100
using namespace std;
//实验内容
//图的存储--邻接矩阵
//深度、广度优先遍历方法
int vexnum,arcnum;//顶点数,边数
int arcs[maxn][maxn];//邻接矩阵
void Init()
{
int a,b;
cout<<"Enter n and m:";
cin>>vexnum>>arcnum;
cout<<"#"<<endl;
for(int i=1;i<=vexnum;i++)//初始化邻接矩阵
{
for(int j=1;j<=vexnum;j++)
{
arcs[i][j]=00;//将所有顶点度数初始化为零
}
}
while(arcnum--)
{
cin>>a>>b;
arcs[a][b]=1;
}
}
void Show()
{
for(int i=1;i<=vexnum;i++)
{
for(int j=1;j<=vexnum;j++)
{
cout<<arcs[i][j]<<" ";
}
cout<<endl;
}
}
int main()
{
Init();
Show();
return 0;
}
*/
//邻接矩阵表示法的优缺点
/*
优点:
1:便于判断两个顶点之间是否有边,即根据A[i][j]=0或1来判断。
2:便于计算各个顶点的度。
缺点:
1:不便于增加和删除顶点。
2:不便于统计边的数目。
3:空间复杂度高。
*/
//邻接表法
//邻接表法
#include<iostream>
#define MAX_VERTEX_NUM 20
using namespace std;
bool visited[MAX_VERTEX_NUM];
class ArcNode//边表结点
{
public:
int adjvex;//该边所指向的顶点位置
ArcNode *nextArc;//指向下一跳边的指针
};
class VNode//表头结点类&&顶点信息
{
public:
string data;
ArcNode *firstArc;//指向第一个邻接点的指针
};
typedef struct QNode
{
int data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct
{
QueuePtr front;
QueuePtr rear;
}LinkQueue;
void InitQueue(LinkQueue &Q)//初始化队列,构造一个空队列
{
Q.front = Q.rear =new QNode;
Q.front->next = NULL;
}
void EnQueue(LinkQueue &Q,int e) //链队的入队,插入元素e为队列新的队尾元素
{
QNode *p = new QNode;
p->data = e;
p->next = NULL;
Q.rear->next = p;
Q.rear = p;
}
bool IsEmpty(LinkQueue &Q)//判空
{
if(Q.front == Q.rear)
return true;
return false;
}
bool DeQueue(LinkQueue &Q,int &e)//出队,队头元素出队,并用e返回其值
{
if(IsEmpty(Q))
return false;
QNode *p = Q.front->next;
e=p->data;
Q.front->next = p->next;
if(Q.rear == p)
Q.rear = Q.front;
delete p;
return true;
}
class AdjGraph
{
public:
VNode vertices[MAX_VERTEX_NUM];
int LocateVex(AdjGraph &G,string v);
bool CreateUDG(AdjGraph &G);
void DFS_AL(AdjGraph &G,int v);
void DFSTraverse(AdjGraph &G);
void BFSTraverse(AdjGraph &G);
int vexnum,arcnum;//图的顶点数和边数
};
int AdjGraph::LocateVex(AdjGraph &G,string v)
{
for(int i=1;i<=G.vexnum;i++)
{
if(G.vertices[i].data==v)
return i;
}
return -1;
}
bool AdjGraph::CreateUDG(AdjGraph &G)
{
cout<<"Input the number of points and edges:";
cin>>G.vexnum>>G.arcnum;
cout<<"Input the information of points:";
for(int i=1;i<=G.vexnum;i++)
{
cin>>G.vertices[i].data;
G.vertices[i].firstArc = NULL;
visited[i]=false;
}
cout<<"Input the information of edge:"<<endl;
for(int k=1;k<=G.arcnum;k++)
{
cout<<"the "<<k<<" edges:";
string v1,v2;
cin>>v1>>v2;
int i=LocateVex(G,v1);
int j=LocateVex(G,v2);
//确定v1和v2在G中的位置
ArcNode *p1 = new ArcNode;
p1->adjvex = j;
p1->nextArc = G.vertices[i].firstArc;
G.vertices[i].firstArc = p1;
ArcNode *p2 = new ArcNode;
p2->adjvex = i;
p2->nextArc = G.vertices[j].firstArc;
G.vertices[j].firstArc = p2;
}
return true;
}
void AdjGraph::DFS_AL(AdjGraph &G,int v)//深度优先遍历
{
cout<<"now is at point "<<v<<" and the data is "<<G.vertices[v].data<<endl;//输出顶点信息
visited[v]=true;//设置该顶点状态为已访问
ArcNode *p = new ArcNode;
p=G.vertices[v].firstArc;//下一个边表结点
while(p!=NULL)
{
int w=p->adjvex;
if(!visited[w])//如果是未访问的则递归
{
DFS_AL(G,w);
}
p=p->nextArc;
}
}
void AdjGraph::DFSTraverse(AdjGraph &G)//深度优先遍历
{
for(int x=1;x<=G.vexnum;x++)//初始化每个顶点都未被访问过
{
visited[x]=false;
}
for(int x=1;x<=G.vexnum;x++)//选取一个未访问的顶点,进行深度优先搜索
{
if(!visited[x])//如果是连通图只执行一次
{
DFS_AL(G,x);
}
}
}
void AdjGraph::BFSTraverse(AdjGraph &G)
{
int z;
LinkQueue LQ;//创建一个队列
InitQueue(LQ);//初始化辅助队列,置空
for(int y=1;y<=G.vexnum;y++)//设置所为顶点为未访问
{
visited[y]=false;
}
for(int y=1;y<=G.vexnum;y++)
{
if(!visited[y])//选取一个未访问的顶点,如果图是连通图,则只执行一次
{
visited[y]=true;
cout<<"now is at point "<<y<<" and the data is "<<G.vertices[y].data<<endl;//输出顶点信息
EnQueue(LQ,y);
while(!IsEmpty(LQ))//队列不为空
{
DeQueue(LQ,z);//队头元素出队,并传值给 z
ArcNode *p=G.vertices[z].firstArc;
while(p)
{
if(!visited[p->adjvex])
{
visited[p->adjvex]=true;
cout<<"now is at point "<<p->adjvex<<" and the data is "<<G.vertices[p->adjvex].data<<endl;//输出顶点信息
EnQueue(LQ,p->adjvex);
}
p = p->nextArc;
}
}
}
}
}
int main()
{
AdjGraph a1;
a1.CreateUDG(a1);
cout<<"The result of DFS:"<<endl;
a1.DFSTraverse(a1);
cout<<"The result of BFS:"<<endl;
a1.BFSTraverse(a1);
}
图
最新推荐文章于 2024-05-04 15:47:39 发布