图的深度广度优先遍历操作代码

图的深度广度优先遍历操作代码
图的深度广度优先遍历操作代码

一、实验目的

1.掌握图的各种存储结构,特别要熟练掌握邻接矩阵和邻接表存储结构;

2.遍历是图各种应用的算法的基础,要熟练掌握图的深度优先遍历和宽度优先遍历算法,复习栈和队列的应用;

3.掌握图的各种应用的算法:图的连通性、连通分量和最小生成树、拓扑排序、关键路径。

二、实验内容

实验内容1**图的遍历

[问题描述]

许多涉及图上操作的算法都是以图的遍历为基础的。写一个程序,演示在连通无向图上遍历全部顶点。

[基本要求]

建立图的邻接表的存储结构,实现无向图的深度优先遍历和广度优先遍历。以用户指定的顶点为起点,分别输出每种遍历下的顶点访问序列。

[实现提示]

设图的顶点不超过30个,每个顶点用一个编号表示(如果一个图有N个顶点,则它们的编号分别为1,2,…,N)。通过输入图的全部边输入一个图,每条边是两个顶点编号对,可以对边依附顶点编号的输入顺序作出限制(例如从小到大)。

[编程思路]

首先图的创建,采用邻接表建立,逆向插入到单链表中,特别注意无向是对称插入结点,且要把输入的字符在顶点数组中定位(LocateVex(Graph G,char *name),以便后来的遍历操作,深度遍历算法采用递归调用,其中最主要的是NextAdjVex(Graph G, int v, int w);FirstAdjVex ()函数的书写,依次递归下去,广度遍历用队列的辅助。

[程序代码]

头文件:

#include

#include

#define MAX_VERTEX_NUM 30

#define MAX_QUEUE_NUMBER 30

#define OK 1

#define ERROR 0

#define INFEASIBLE -1

#define OVERFLOW -2

#define TRUE 1

#define FALSE 0

typedef int Status;

typedef int InfoType;

typedef int Status;

/* 定义弧的结构*/

typedef struct ArcNode{

int adjvex; /*该边所指向的顶点的位置*/ struct ArcNode *nextarc; /*指向下一条边的指针*/ InfoType info; /*该弧相关信息的指针*/

}ArcNode;

/*定义顶点的结构*/

typedef struct VNode{

char data[40]; /*顶点信息*/

ArcNode *firstarc; /*指向第一条依附该顶点的弧的指针*/

}VNode,AdjList[MAX_VERTEX_NUM];

/*定义图的结构*/

typedef struct {

AdjList vertices;

int vexnum,arcnum; /*图的当前顶点数和弧数*/

int kind; /*图的类型标志*/

}Graph;

/*定义队列的结构*/

typedef struct{

int *elem;

int front, rear;

}Queue;

/*功能选择*/

void MenuSelect(int w);

/*顶点定位*/

int LocateVex(Graph G,char *name);

/*创建无向图*/

void CreateGraph(Graph &G);

/*求第一个顶点*/

int FirstAdjVex(Graph G, int v);

/*求下一个顶点*/

int NextAdjVex(Graph G, int v, int w);

/*深度递归*/

void DFS(Graph G, int v) ;

/*深度遍历*/

void DFSTravel(Graph G,int v);

/*广度遍历*/

void BFSTraverse(Graph G,char *name);

/*初始化队列*/

Status InitQueue(Queue &Q);

/*判空*/

Status EmptyQueue(Queue Q);

/*进队*/

Status EnQueue(Queue &Q, int e);

/*出队*/

Status DeQueue(Queue &Q, int &e);

实现文件:

#include

#include"malloc.h"

#include "tuhead.h"

#include "stdlib.h"

#include "string.h"

bool visited[MAX_VERTEX_NUM];

/***********************************************************

* 顶点定位*

***********************************************************/

int LocateVex(Graph G,char *name)

{

int i;

for(i=1;i<=G.vexnum;i++) //从1号位置开始存储if(strcmp(name,G.vertices[i].data)==0) //相等则找到,返回位序return i;

return -1;

}

/***********************************************************

* 创建无向图*

***********************************************************/

void CreateGraph(Graph &G)

{

ArcNode *p;

char name1[10],name2[10];

int i,j,k;

printf(" 请输入顶点数,按回车键结束:");

scanf("%d",&G.vexnum);

printf(" 请输入弧数,按回车键结束:");

scanf("%d",&G.arcnum);

printf(" 请依次输入顶点名(用空格分开且字符小于10),按回车键结束:\n");

printf(" ");

for(i=1;i<=G.vexnum;i++) //从1号位置开始存储

{

scanf("%s",G.vertices[i].data); //从一号位置开始初始化

G.vertices[i].firstarc=NULL;

}

printf("\n\n\n\n");

printf(" ………………………………………输入小提示………………………………………\n");

printf(" &&&&1 为避免输入遗漏,最好从选择任意一点,输入所有相邻边\n");

printf(" &&&&2 输入边时格式(用空格分开,即格式为顶点(空格)顶点(空格))\n");

printf(" ………………………………………输入小提示………………………………………\n\n\n\n");

for(k=0;k

{

printf("请输入相邻的两个顶点,按回车键结束:");

scanf("%s%s",name1,name2);

i=LocateVex(G,name1); //返回位序

j=LocateVex(G,name2);

p=(ArcNode *)malloc(sizeof(ArcNode)); //申请边节点

p->adjvex=j; //插入到邻接表中,注意此处为逆向插入到单链表中p->nextarc=G.vertices[i].firstarc;

G.vertices[i].firstarc=p;

//无向图,注意是对称插入结点p=(ArcNode *)malloc(sizeof(ArcNode));

p->adjvex=i;

p->nextarc=G.vertices[j].firstarc;

G.vertices[j].firstarc=p;

}

}

/***********************************************************

* 求第一个顶点*

***********************************************************/

int FirstAdjVex(Graph G, int v)

{

ArcNode *p;

if(v>=1 && v<=G.vexnum)

{

p=G.vertices[v].firstarc;

if(p->nextarc==NULL)

return 0;

else

return (p->nextarc->adjvex); //返回第一个顶点字符

}

return -1;

}

/***********************************************************

* 求下一个顶点*

***********************************************************/

int NextAdjVex(Graph G, int v, int w)

{ //在图G中寻找第v个顶点的相对于w的下一个邻接顶点ArcNode *p;

if(v>=1 && v<=G.vexnum && w>=1 && w<=G.vexnum)

{

p=G.vertices[v].firstarc;

while(p->adjvex!=w)

p=p->nextarc; //在顶点v的弧链中找到顶点w

if(p->nextarc!=NULL)

return 0; //若已是最后一个顶点,返回0 else

return(p->nextarc->adjvex); //返回下一个邻接顶点的序号

}

return -1;

}

/***********************************************************

* 深度递归*

***********************************************************/

void DFS(Graph G, int v)

{

int w;

ArcNode *p;

visited[v]=1;

printf("%s ",G.vertices[v].data); //访问第v个顶点

p=G.vertices[v].firstarc; //p为依附顶点的第一条边while (p!=NULL)

{

w=p->adjvex;

if(visited[w]==0)

DFS(G,w);

p=p->nextarc; //下移指针

}

}

/***********************************************************

* 深度遍历*

***********************************************************/

void DFSTravel(Graph G,int v)

{

for(int i=1;i<=G.vexnum;i++)

visited[i]=0;

int w;

ArcNode *p;

visited[v]=1;

printf("%s ",G.vertices[v].data); //访问第v个顶点p=G.vertices[v].firstarc;

while (p!=NULL)

{

w=p->adjvex;

if(visited[w]==0)

DFS(G,w);

p=p->nextarc;

}

}

/***********************************************************

* 初始化队列*

***********************************************************/

Status InitQueue(Queue &Q)

{

Q.elem = new int[MAX_QUEUE_NUMBER];

Q.front = Q.rear = 0;

return OK;

相关文档
最新文档