- 图的邻接表的存储方法
- 图的深度优先遍历和广度优先遍历
1.由给定的图的邻接矩阵建立图的邻接表并显示出来;
2.给出从结点a开始的图的深度优先遍历序列;
3.给出从结点a开始的图的广度优先遍历序列。
图的顶点信息和邻接矩阵如下所示:
main.cpp
#define N 5 //顶点个数
#include "AdjGraph.h"
int main(int argc, char** argv) {
//定义顶点信息
char vex[N]={'a','b','c','d','e'};
//*定义邻接矩阵(带权有向图)
int A[N][N]={
{0,6,2,INF,INF},
{INF,0,INF,INF,3},
{INF,3,0,1,INF},
{INF,4,INF,0,5},
{INF,INF,INF,INF,0}
};
//*/
/*定义邻接矩阵(带权无向图)
int A[N][N]={
{0,6,2,INF,INF},
{6,0,3,4,3},
{2,3,0,1,INF},
{INF,4,1,0,5},
{INF,3,INF,5,0}
};
//*/
AdjGraph *G;
CreateAdj(G,A,vex,5,7);
DispAdj(G);
printf("图顶点数和边数分别为:(%d,%d)",G->n,G->e);
//*/
//*深度优先遍历算法
printf("\n\n\n深度优先遍历:");
DFS(G,0);
// printf("\n\n\n");
// DFS1(G);
//*/
//*广度优先遍历算法
printf("\n\n\n广度优先遍历:");
BFS(G,0);
// printf("\n\n\n");
// BFS1(G);
//*/
printf("\n\n\n");
return 0;
}
AdjGraph.h
#include <malloc.h>
#include <stdio.h>
#define INF 32767 //INF表示∞
#define MAXV 20 // 最大顶点个数
typedef char InfoType;
//边节点类型
typedef struct ANode
{
//边的终点编号
int adjvex;
//下一条边的指针
struct ANode *nextarc;
//边的相关信息
int weight;
}ArcNode;
//邻接表头节点类型
typedef struct VNode
{
//顶点信息
InfoType info;
//指向第一条边
ArcNode *firstarc;
}VNode;
//图邻接表类型
typedef struct
{
//邻接表
VNode adjlist[ MAXV ];
//n为顶点数、e为边数
int n, e;
}AdjGraph;
void CreateAdj(AdjGraph *&G, int A[N][N], char V[N], int n, int e)
{
int i,j;
ArcNode *p;
G=(AdjGraph *)malloc(sizeof(AdjGraph));
for(i=0;i<n;i++)
{
G->adjlist[i].info = V[i];
G->adjlist[i].firstarc = NULL;
}
for(i=0;i<n;i++)
for(j=n-1;j>=0;j--)
if(A[i][j] != 0 && A[i][j] != INF)
{
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("%d(%c): ",i,G->adjlist[i].info);
while(p!=NULL)
{
printf("%d[%d]->",p->adjvex,p->weight);
p=p->nextarc;
}
printf("^\n");
}
}
//----------------------------------深度遍历
//(强)连通图深度优先遍历算法
int visited[MAXV]={0};
void DFS(AdjGraph *G,int v)
{
ArcNode *p;
visited[v]=1;
printf("%d(%c)",v,G->adjlist[v].info); //输出v编码和顶点信息
//深度优先遍历与v相邻的未被访问的结点
p=G->adjlist[v].firstarc;
while(p!=NULL)
{
if(visited[p->adjvex] == 0)
DFS(G,p->adjvex);
p = p->nextarc;
}
}
//非(强)连通图的深度优先遍历算法
void DFS1(AdjGraph *G)
{
int i;
for(i=0;i<G->n;i++)
if(visited[i]==0) DFS(G,i);
}
//----------------------------------广度遍历
//(强)连通图的广度优先遍历算法
#include "LinkQueue.h"
void BFS(AdjGraph *G,int v)
{
int w,i;
ArcNode *p;
LiQueue *qu;
InitQueue(qu);
for(i=0;i<G->n;i++) visited[i]=0;
visited[v]=1;
printf("%d(%c)",v,G->adjlist[v].info); //输出v编码和顶点信息
enQueue(qu,v);
while(!QueueEmpty(qu))//只要队列不为空
{
deQueue(qu,w);
p=G->adjlist[w].firstarc;
while(p!=NULL)
{
if(visited[p->adjvex] == 0)
{
printf("%d(%c)",p->adjvex,G->adjlist[p->adjvex].info); //输出v编码和顶点信息
visited[p->adjvex]=1;
enQueue(qu,p->adjvex);
}
p=p->nextarc;
}
}
}
//非(强)连通图的广度优先遍历算法
void BFS1(AdjGraph *G)
{
int i;
for(i=0;i<G->n;i++)
if(visited[i]==0) BFS(G,i);
}
LinkQueue.h
#include <malloc.h>
#include <stdio.h>
typedef int ElemType;
//----- 队列的链式存储-----
typedef struct qnode
{ // 结点类型
ElemType data;
struct qnode *next;
} QNode;
typedef struct
{ // 链队列类型
QNode* front; // 队头指针
QNode* rear; // 队尾指针
}LiQueue;
void InitQueue(LiQueue *&q)
{
q=(LiQueue *)malloc(sizeof(LiQueue));
q->front=q->rear=NULL;
}
void DestroyQueue(LiQueue *&q)
{
QNode *p=q->front,*r; //p指向队头数据节点
if (p!=NULL) //释放数据节点占用空间
{
r=p->next;
while (r!=NULL)
{
free(p);
p=r;
r=p->next;
}
}
free(p);
free(q); //释放链队节点占用空间
}
bool QueueEmpty(LiQueue *q)
{
return(q->rear==NULL);
}
void enQueue(LiQueue *&q,ElemType e)
{
QNode *p;
p=(QNode *)malloc(sizeof(QNode));
p->data=e;
p->next=NULL;
if (q->rear==NULL) //若链队为空,新节点是队首节点又是队尾节点
q->front=q->rear=p;
else
{
q->rear->next=p;//将*p节点链到队尾,并将rear指向它
q->rear=p;
}
}
bool deQueue(LiQueue *&q,ElemType &e)
{
QNode *t;
if (q->rear==NULL)
return false; //队列为空
t=q->front; //t指向第一个数据节点
if (q->front==q->rear) //队列中只有一个节点时
q->front=q->rear=NULL;
else //队列中有多个节点时
q->front=q->front->next;
e=t->data;
free(t);
return true;
}
void DispQueue(LiQueue *q)
{ //从队头到队尾,逐个显示出来
QNode *p= q->front;
while(p != NULL)
{
printf("%4d",p->data);
p = p->next;
}
}