数据结构学习之图的遍历(邻接表和邻接矩阵)
0x1 问题描述
建立一个邻接表和邻接矩阵的算法
0x2 代码如下
#include <iostream>
#include <string.h>
#include <cstdio>
#include <cstdlib>
#define MAXV 1000+7
#define INF 32767
using namespace std;
//邻接矩阵结构
typedef struct
{
int no;
//InfoType info;
}VertextType;
typedef struct
{
int edge[MAXV][MAXV];
int n; //vertex number
int e; //edge number
VertextType vers[MAXV];
}MatGraph;
// 创建图
void CreateMat(MatGraph *&g,int n, int e)
{
//Init
int i=0,j=0,v=0;
g->n=n;
g->e=e;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(i!=j)
g->edge[i][j]=INF;
else
g->edge[i][j]=0;
for(int n=1;n<=e;n++)
{
cin>>i>>j>>v;
g->edge[i][j]=v;
}
}
// 输出图
void DispMat(MatGraph *g)
{
for(int i=0;i<g->n;i++)
for(int j=0;j<g->n;j++)
{
cout<< g->edge[i][j] <<"\t";
if(j==g->n-1)
cout<<endl;
}
}
// 销毁图
void DestroyMat(MatGraph *&g)
{
free(g);
}
//邻接表结构
typedef struct ANode
{
int adjvex;
struct ANode *nextarc; //指向下一条边的指针
int weight;
}ArcNode;
typedef struct Vnode
{
//InfoType info;
ArcNode *firstarc; //指向第一个边结点
}VNode;
typedef struct
{
int n;
int e;
VNode adjlist[MAXV]; //邻接表的头结点数组
}AdjGraph;
//创建邻接表
void CreateAdj(AdjGraph *&G,int A[MAXV][MAXV],int n,int e)
{
ArcNode *p;
G=(AdjGraph *)malloc(sizeof(AdjGraph));
for(int i=0;i<n;i++)
G->adjlist[i].firstarc=NULL;
for(int i=0;i<n;i++)
for(int j=n-1;j>=0;j--)
{
if(A[i][j]!=0 && A[i][j]!=INF)
{
//insert head method
p=(ArcNode *)malloc(sizeof(ArcNode));
p->adjvex=j;
p->weight=A[i][j];
p->nextarc=G->adjlist[i].firstarc;
G->adjlist[i].firstarc=p;
}
}
G->n=n;
G->e=e;
}
//输出邻接表
void DispAdj(AdjGraph *G)
{
ArcNode *p;
for(int i=0;i<G->n;i++)
{
p=G->adjlist[i].firstarc;
printf("%3d:",i);
while(p!=NULL)
{
printf("%3d[%d]",p->adjvex,p->weight);
p=p->nextarc;
}
printf("\n");
}
}
// 销毁邻接表
void DestroyAdj(AdjGraph *&G)
{
ArcNode *pre,*p;
for(int i=0;i<G->n;i++)
{
p=G->adjlist[i].firstarc;
while(p!=NULL)
{
pre=p;
p=p->nextarc;
free(pre);
}
}
free(G);
}
int main()
{
int n,e;
cout<< "Please input the number of vertex(n) and edge(e):"<<endl;
cin>>n>>e;
MatGraph *G = (MatGraph *)malloc(sizeof(MatGraph));
CreateMat(G,n,e);
DispMat(G);
AdjGraph *g;
CreateAdj(g,G->edge,n,e);
DispAdj(g);
DestroyAdj(g);
DestroyMat(G)
return 0;
}
0x3 问题描述
> 实现图的遍历算法
>
> ![image-20190514151953196](https://ws2.sinaimg.cn/large/006tNc79ly1g30vea93y4j31880kaws5.jpg)
数据如下:
6 9
0 1 5
1 2 4
3 2 5
4 3 5
5 4 1
2 0 8
2 5 9
0 3 7
3 5 6
0x4 代码如下
附加说明:
这里我对两种存储结构,邻接表和邻接矩阵,每种都分别写了DFS的递归和非递归遍历、BFS遍历。
网上很多代码其实有错误的,我检验了下自己的代码,觉得还ok.
#include <iostream>
#include <string.h>
#include <queue>
#include <stack>
#include <cstdio>
#include <cstdlib>
#define MAXV 1000+7
#define INF 32767
using namespace std;
//邻接矩阵结构
typedef struct
{
int no;
//InfoType info;
}VertextType;
typedef struct
{
int edge[MAXV][MAXV];
int n; //vertex number
int e; //edge number
VertextType vers[MAXV];
}MatGraph;
// 创建图
void CreateMat(MatGraph *&g,int n, int e)
{
//Init
int i=0,j=0,v=0;
g->n=n;
g->e=e;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(i!=j)
g->edge[i][j]=INF;
else
g->edge[i][j]=0;
for(int n=1;n<=e;n++)
{
cin>>i>>j>>v;
g->edge[i][j]=v;
}
}
// 输出图
void DispMat(MatGraph *g)
{
for(int i=0;i<g->n;i++)
for(int j=0;j<g->n;j++)
{
cout<< g->edge[i][j] <<"\t";
if(j==g->n-1)
cout<<endl;
}
}
// 销毁图
void DestroyMat(MatGraph *&g)
{
free(g);
}
//邻接表结构
typedef struct ANode
{
int adjvex;
struct ANode *nextarc; //指向下一条边的指针
int weight;
}ArcNode;
typedef struct Vnode
{
//InfoType info;
int d;
ArcNode *firstarc; //指向第一个边结点
}VNode;
typedef struct
{
int n;
int e;
VNode adjlist[MAXV]; //邻接表的头结点数组
}AdjGraph;
typedef struct
{
int n;
ArcNode *d;
}Node;
//创建邻接表
void CreateAdj(AdjGraph *&G,int A[MAXV][MAXV],int n,int e)
{
ArcNode *p;
G=(AdjGraph *)malloc(sizeof(AdjGraph));
for(int i=0;i<n;i++)
G->adjlist[i].firstarc=NULL;
for(int i=0;i<n;i++)
for(int j=n-1;j>=0;j--)
{
if(A[i][j]!=0 && A[i][j]!=INF)
{
//insert head method
p=(ArcNode *)malloc(sizeof(ArcNode));
p->adjvex=j;
p->weight=A[i][j];
p->nextarc=G->adjlist[i].firstarc;
G->adjlist[i].firstarc=p;
}
}
G->n=n;
G->e=e;
}
//输出邻接表
void DispAdj(AdjGraph *G)
{
ArcNode *p;
for(int i=0;i<G->n;i++)
{
p=G->adjlist[i].firstarc;
printf("%3d:",i);
while(p!=NULL)
{
printf("%3d[%d]",p->adjvex,p->weight);
p=p->nextarc;
}
printf("\n");
}
}
// 销毁邻接表
void DestroyAdj(AdjGraph *&G)
{
ArcNode *pre,*p;
for(int i=0;i<G->n;i++)
{
p=G->adjlist[i].firstarc;
while(p!=NULL)
{
pre=p;
p=p->nextarc;
free(pre);
}
}
free(G);
}
/*
data
6 9
0 1 5
1 2 4
3 2 5
4 3 5
5 4 1
2 0 8
2 5 9
0 3 7
3 5 6
*/
//recrusive method DFS
int visted[MAXV];
void DFS(AdjGraph *G,int v)
{
ArcNode *p;
visted[v]=1;
printf("%2d",v);
p = G->adjlist[v].firstarc;
while(p!=NULL)
{
if(visted[p->adjvex]==0)
DFS(G,p->adjvex);
else
p=p->nextarc;
}
}
// 邻接矩阵dfs
void dfs(MatGraph *G,int v)
{
visted[v]=1;
printf("%2d",v);
for(int i=0;i<G->n;i++)
{
if(G->edge[v][i]<INF && visted[i]==0 && G->edge[v][i]!=0)
dfs(G,i);
}
}
// not recrusive method DFS
// 失败
void DfsStack(AdjGraph *G,int v)
{
//ArcNode *p;
Node v1,v2;
stack<Node>s;
memset(visted,0,sizeof(visted));
v1.n=v;
v1.d=G->adjlist[v].firstarc;
visted[v1.n]=1;
printf("%2d",v1.n);
s.push(v1);
while(!s.empty())
{
v1=s.top();
bool find=false;
while(v1.d!=NULL && !find)
{
if(visted[v1.d->nextarc->adjvex]==0)
find=true;
else
{
v1.d = v1.d->nextarc;
}
}
if(find)
{
v2.n=G->adjlist[v1.d->nextarc->adjvex].firstarc->adjvex;
v2.d=G->adjlist[v1.d->nextarc->adjvex].firstarc;
printf("%2d",v1.n);
s.push(v2);
visted[v2.n]=1;
}else
{
s.pop();
//visted[v1.n]=0;
}
}
printf("\n");
}
void DFS_STACK(AdjGraph *G,int v)
{
stack<int>s;
ArcNode *p;
int booked[MAXV];
for(int i=0;i<G->n;i++)
booked[i]=0;
s.push(v);
printf("%2d",v);
booked[v]=1;
p=G->adjlist[v].firstarc;
while(!s.empty())
{
int v1=s.top();
p=G->adjlist[v1].firstarc;
while(p)
{
if(booked[p->adjvex]==0)
{
printf("%2d",p->adjvex);
booked[p->adjvex]=1;
s.push(p->adjvex);
p=G->adjlist[p->adjvex].firstarc;
}else
{
p=p->nextarc;
}
}
if(p==NULL)
s.pop();
}
}
void dfs_stack(MatGraph *G,int v)
{
stack<int> s;
int i;
int booked[MAXV];
for(int i=0;i<G->n;i++)
booked[i]=0;
s.push(v);
booked[v]=1;
printf("%2d",v);
while(!s.empty())
{
int v1=s.top();
for(i=0;i<G->n;i++)
{
if(G->edge[v1][i]<INF && booked[i]==0 && G->edge[v1][i]!=0)
{
printf("%2d",i);
s.push(i);
booked[i]=1;
break;
}
}
if(i==G->n)
s.pop();
}
}
/*
void DFSTraverse(AdjGraph *G,int v)
{
int top=-1;
int j;
printf("%2d",v);
visted[v]=1;
stack[++top]=v;
while(top!=-1)
{
v=stack[top];
for(int i=0;i<G.n;i++)
{
if(G)
}
}
}
*/
// BFS
void BFS(AdjGraph *G,int v)
{
queue<int>q;
ArcNode *p;
int visted[MAXV];
for(int i=0;i<G->n;i++)
visted[i]=0;
printf("%2d",v);
visted[v]=1;
q.push(v);
while(!q.empty())
{
int v1=q.front();
q.pop();
p=G->adjlist[v1].firstarc;
while(p!=NULL)
{
if(visted[p->adjvex]==0)
{
printf("%2d",p->adjvex);
visted[p->adjvex]=1;
q.push(p->adjvex);
}
p=p->nextarc;
}
}
printf("\n");
}
void bfs(MatGraph *G,int v)
{
queue<int> q;
int booked[MAXV];
for(int i=0;i<G->n;i++)
booked[i]=0;
q.push(v);
booked[v]=1;
printf("%2d",v);
while(!q.empty())
{
int v1=q.front();
q.pop();
for(int i=0;i<G->n;i++)
{
if(G->edge[v1][i]<INF && booked[i]==0 && G->edge[v][i]!=0)
{
printf("%2d",i);
q.push(i);
booked[i]=1;
}
}
}
}
int main()
{
int n,e;
cout<< "Please input the number of vertex(n) and edge(e):"<<endl;
cin>>n>>e;
MatGraph *G = (MatGraph *)malloc(sizeof(MatGraph));
CreateMat(G,n,e);
DispMat(G);
AdjGraph *g;
CreateAdj(g,G->edge,n,e);
DispAdj(g);
memset(visted,0,sizeof(visted));
printf("遍历邻接表Start\n");
DFS(g,0);
printf("\n");
//非递归遍历
DFS_STACK(g,0);
printf("\n");
BFS(g,0);
printf("\n遍历邻接矩阵Start\n");
memset(visted,0,sizeof(visted));
dfs(G,0);
printf("\n");
//非递归遍历
dfs_stack(G,0);
printf("\n");
bfs(G,0);
return 0;
}