无向图的存储结构
⑴ 建立图的存储结构(图的类型可以是有向图、无向图、有向网、无向网,学生可以任选
链表
⑵ 要求采用邻接矩阵作为无向图的存储结构,邻接表作为有向图的存储结构,完成无向图和有向图的建立,并对建
#include"utility.h"
#include"adj_matrix_undir_graph.h"
#include"adj_list_dir_graph.h"
#include"dfs.h"
#include"bfs.h"
int main(void)
{
int n,j=0,i=0;
int m,e,b=0;
char vexs[20],c;
char nums[20];
cout<<"输入无向图的顶点个数n:"<<endl;
cin>>n;
cout<<"输入顶点元素:"<<endl;
for(i=0;i<n;i++)
{
cout<<"请输入第"<<j<<"个结点"<<endl;
cin>>vexs[i];
j++;
}
cout<<"输出无向图的邻接矩阵:"<<endl;
AdjMatrixUndirGraph<char> aundir(vexs,n);
for(i=0;i<n;i++)
{
for(int v=1;v<n;v++)
{
cout<<"输入Y/N,是否插入边:";
cin>>c;
if(c == 'Y' )
aundir.InsertEdge(i,v);
}
}
Display(aundir);
cout<<"请输入有向图的顶点个数m:";
cin>>m;
for(int a=0;a<m;a++)
{
cout<<"输入第"<<b<<"个顶点数据";
cin>>nums[a];
b++;
}
AdjListDirGraph<char> dir(nums,m);
for(int k=0;k<m;k++)
{
for(e=0;e<m;e++)
{
cout<<"是否插入边V"<<k<<",V"<<e<<":";
cin>>c;
if(c == 'Y' )
dir.InsertEdge(k,e);
}
}
Display(dir);
cout<<"无向图的深度遍历:";
DFSTraverse<char>(aundir,Write<char>);
cout<<endl;
cout<<"无向图的广度遍历:";
BFSTraverse<char>(aundir,Write<char>);
cout<<endl;
cout<<"有向图的深度遍历:";
DFSTraverse<char>(dir,Write<char>);
cout<<endl;
cout<<"有向图的广度遍历:";
BFSTraverse<char>(dir,Write<char>);
⑶ 无向图 其临街矩阵存储结构共有多少元素
因为有n个顶点,所以有n*n个元素,2*e个非零元素(无向图,对称),所以有n*n-2*e个零元素.
⑷ 怎样将一棵二叉树的存储结构转化为一个无向图的存储结构,谁能说说编程思想啊
图的存储机构一般用邻接矩阵或邻接表,二叉树一般是链表结构,就是把链表变成临近矩阵了,用中序形势对链表节点进行编号和访问并做为临近矩阵的顺序,用中序访问,对当前节点和后继节点判断,然后置对应的矩阵为1,(a[当前],[后继]=1 ,a[后继],[当前]=1 ) ,中序访问完就可以了
⑸ 求用C语言和数据结构中的无向图存储结构编一个校园导游图完全的程序代码
#define Infinity 1000
#define MaxVertexNum 35
#define MAX 40
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<string.h>
#include<iostream.h>
typedef struct arcell //边的权值信息
{
int adj; //权值
}arcell,adjmatrix[MaxVertexNum][MaxVertexNum]; //图的邻接矩阵类型
typedef struct vexsinfo //顶点信息
{
int position; //景点的编号
char name[32]; //景点的名称
char introction[256]; //景点的介绍
}vexsinfo;
typedef struct mgraph //图结构信息
{
vexsinfo vexs[MaxVertexNum]; //顶点向量(数组)
adjmatrix arcs; //邻接矩阵
int vexnum,arcnum; //分别指定顶点数和边数
}mgraph;
//全局变量
int visited[35]; //用于标志是否已经访问过
int d[35]; //用于存放权值或存储路径顶点编号
mgraph campus; //图变量(大学校园)
// (1) 对图初始化
mgraph initgraph()
{
int i=0,j=0;
mgraph c;
c.vexnum =28; //顶点个数
c.arcnum =39; //边的个数
for(i=0;i<c.vexnum ;i++) //依次设置顶点编号
c.vexs[i].position =i;
//依次输入顶点信息
strcpy(c.vexs[0].name ,"小西南门");
strcpy(c.vexs[0].introction ,"离公交站近");
strcpy(c.vexs[1].name ,"学校南正门");
strcpy(c.vexs[1].introction ,"学校大门、学校班车进出口");
strcpy(c.vexs[2].name ,"语言文化职业学院");
strcpy(c.vexs[2].introction ,"语言文化职业学院办公楼,楼高6层");
strcpy(c.vexs[3].name ,"艺术学院");
strcpy(c.vexs[3].introction ,"音乐系、美术系,楼高4层");
strcpy(c.vexs[4].name ,"行政楼");
strcpy(c.vexs[4].introction ,"行政办公大楼,楼高5层");
strcpy(c.vexs[5].name,"文学院");
strcpy(c.vexs[5].introction ,"文学院,楼高6层");
strcpy(c.vexs[6].name ,"体育场");
strcpy(c.vexs[6].introction ,"室外标准田径场");
strcpy(c.vexs[7].name,"教育科学学院");
strcpy(c.vexs[7].introction ,"教心系、经管系,楼高5层");
strcpy(c.vexs[8].name ,"南区学生宿舍");
strcpy(c.vexs[8].introction ,"离西南门近");
strcpy(c.vexs[9].name, "数学与经济管理学院");
strcpy(c.vexs[9].introction , "数学与经济管理学院大楼,楼高4层");
strcpy(c.vexs[10].name ,"中区学生宿舍");
strcpy(c.vexs[10].introction ,"若干栋,离学生1、2食堂近");
strcpy(c.vexs[11].name ,"职业学院教学大楼");
strcpy(c.vexs[11].introction ,"职业学院教学大楼,楼高5层");
strcpy(c.vexs[12].name ,"体育系");
strcpy(c.vexs[12].introction ,"体育系,楼高5层");
strcpy(c.vexs[13].name ,"游泳馆");
strcpy(c.vexs[13].introction ,"室内小型游泳馆");
strcpy(c.vexs[14].name ,"报告厅、阶梯教室");
strcpy(c.vexs[14].introction ,"可举办中、大型学术会议。有大小报告厅1-6个、阶梯教室1-6个");
strcpy(c.vexs[15].name ,"大礼堂、体育馆");
strcpy(c.vexs[15].introction ,"文艺演出所在地、室内运动场");
strcpy(c.vexs[16].name ,"1食堂");
strcpy(c.vexs[16].introction ,"教工食堂及学生1食堂在此");
strcpy(c.vexs[17].name ,"新图书馆");
strcpy(c.vexs[17].introction ,"建筑面积46000平方米");
strcpy(c.vexs[18].name ,"2食堂");
strcpy(c.vexs[18].introction ,"学校东区,学生食堂");
strcpy(c.vexs[19].name ,"东区学生宿舍");
strcpy(c.vexs[19].introction ,"离学生2食堂近");
strcpy(c.vexs[20].name ,"计算机学院");
strcpy(c.vexs[20].introction ,"计算机学院大楼,楼高5层");
strcpy(c.vexs[21].name ,"教工宿舍");
strcpy(c.vexs[21].introction ,"学校青年教职工租住地");
strcpy(c.vexs[22].name ,"西区学生宿舍");
strcpy(c.vexs[22].introction ,"离学生3、4食堂近");
strcpy(c.vexs[23].name ,"3食堂");
strcpy(c.vexs[23].introction ,"学校西区,学生食堂");
strcpy(c.vexs[24].name ,"外国语学院");
strcpy(c.vexs[24].introction ,"外国语学院大楼,楼高5层");
strcpy(c.vexs[25].name ,"4食堂");
strcpy(c.vexs[25].introction ,"学校西区,学生食堂,人气较高");
strcpy(c.vexs[26].name ,"校医院");
strcpy(c.vexs[26].introction ,"看小病的地方");
strcpy(c.vexs[27].name ,"实验楼");
strcpy(c.vexs[27].introction ,"物电学院、化学与生命科学学院、机电系、建材系所在地,机房及多媒体教室若干");
//依次输入边上的权值信息
for(i=0;i<c.vexnum ;i++)
for(j=0;j<c.vexnum ;j++)
c.arcs [i][j].adj =Infinity; //先初始化图的邻接矩阵
//部分弧长
c.arcs[0][2].adj=50; c.arcs[0][3].adj=60;
c.arcs[1][4].adj=90;
c.arcs[2][3].adj=60; c.arcs[2][8].adj=40;
c.arcs[3][4].adj=60; c.arcs[3][6].adj=40;
c.arcs[4][5].adj=70; c.arcs[4][9].adj=70; c.arcs[4][10].adj=80; c.arcs[4][17].adj=200;
c.arcs[5][7].adj=70;
c.arcs[6][9].adj=40;
c.arcs[7][18].adj=190;
c.arcs[8][11].adj=50;
c.arcs[9][12].adj=40;
c.arcs[10][18].adj=70;
c.arcs[11][12].adj=60; c.arcs[11][14].adj=50; c.arcs[11][15].adj=50;
c.arcs[12][16].adj=50;
c.arcs[13][14].adj=40; c.arcs[13][22].adj=60;
c.arcs[14][15].adj=50; c.arcs[14][20].adj=90;
c.arcs[15][16].adj=60; c.arcs[15][21].adj=40;
c.arcs[16][17].adj=60;
c.arcs[17][18].adj=80;
c.arcs[18][19].adj=60;
c.arcs[20][21].adj=60; c.arcs[20][24].adj=80;
c.arcs[22][23].adj=60; c.arcs[22][25].adj=80;
c.arcs[23][24].adj=60;
c.arcs[24][26].adj=100; c.arcs[24][27].adj=100;
c.arcs[25][26].adj=90;
c.arcs[26][27].adj=90;
for(i=0;i<c.vexnum ;i++) //邻接矩阵是对称矩阵,对称赋值
for(j=0;j<c.vexnum ;j++)
c.arcs[j][i].adj =c.arcs[i][j].adj ;
return c;
}//initgraph
// (2) 查找景点在图中的序号
int locatevex(mgraph c,int v)
{
int i;
for(i=0;i<c.vexnum ;i++)
if(v==c.vexs[i].position)
return i; //找到,返回顶点序号i
return -1; //否则,返回-1
}
//(3) 、(4) 求两景点间的所有路径
// (3) 打印序号为m,n景点间的长度不超过8个景点的路径
void path(mgraph c, int m,int n,int k)
{
int s,x=0;
int t=k+1; //t 记载路径上下一个中间顶点在d[]数组中的下标
if(d[k]==n && k<8) //d[k]存储路径顶点。若d[k]是终点n且景点个数<=8,则输出该路径
{ //递归出口,找到一条路径
for(s=0;s<k;s++)
printf("%s--->",c.vexs[d[s]].name); //输出该路径。s=0 时为起点m
printf("%s",c.vexs[d[s]].name); //输出最后一个景点名(即顶点n的名字,此时s==k)
printf("\n\n");
}
else
{
s=0;
while(s<c.vexnum) //从第m个顶点,试探至所有顶点是否有路径
{
if((c.arcs[d[k]][s].adj<Infinity) && (visited[s]==0)) //初态:顶点m到顶点s有边,且未被访问
{
visited[s]=1;
d[k+1]=s; //存储顶点编号s 至d[k+1]中
path(c,m,n,t); //求从下标为t=k+1的第d[t]个顶点开始的路径(递归调用),同时打印出一条m至n的路径
visited[s]=0; //将找到的路径上顶点的访问标志重新设置为0,以用于试探新的路径
}
s++; //试探从下一个顶点 s 开始是否有到终点的路径
}//endwhile
}//endelse
}//endpath
//(4) 打印两景点间的景点个数不超过8的所有路径。调用(3)
int allpath(mgraph c)
{
int k,i,j,m,n;
printf("\n\n请输入你要查询的两个景点编号:\n\n");
scanf("%d%d",&i,&j);
printf("\n\n");
m=locatevex(c,i); //调用(2),确定该顶点是否存在。若存在,返回该顶点编号
n=locatevex(c,j);
d[0]=m; //存储路径起点m (int d[]数组是全局变量)
for(k=0;k<c.vexnum;k++) //全部顶点访问标志初值设为0
visited[k]=0;
visited[m]=1; //第m个顶点访问标志设置为1
path(c,m,n,0); //调用(3)。k=0,对应起点d[0]==m。k为d[]数组下标
return 1;
}
// (5) 用迪杰斯特拉算法,求出一个景点到其他景点间的最短路径,并打印
void shortestpath_dij(mgraph c)
{
//迪杰斯特拉算法,求从顶点v0到其余顶点的最短路经及其带权长度d[v]
//若p[v][w]为1,则w是从v0到v的最短路经上的顶点
//final[v]类型用于设置访问标志
int v,w,i,min,t=0,x,flag=1,v0; //vo为起始景点的编号
int final[35],d[35],p[35][35];
printf("\n请输入一个起始景点的编号:");
scanf("%d",&v0);
printf("\n\n");
while(v0<0||v0>c.vexnum)
{
printf("\n你所输入的景点编号不存在\n");
printf("请重新输入:");
scanf("%d",&v0);
}//while
for(v=0;v<c.vexnum ;v++)
{
final[v]=0; //初始化各顶点访问标志
d[v]=c.arcs[v0][v].adj; //v0 到各顶点 v 的权值赋值给d[v]
for(w=0;w<c.vexnum ;w++) //初始化p[][]数组,各顶点间的路径全部设置为空路径0
p[v][w]=0;
if(d[v]<Infinity) //v0 到v 有边相连,修改p[v][v0]的值为1
{
p[v][v0]=1;
p[v][v]=1; //各顶点自己到自己要连通
}
}//for
d[v0]=0; //自己到自己的权值设为0
final[v0]=1; //v0的访问标志设为1,v 属于 s 集
for(i=1;i<c.vexnum ;i++) //对其余c.vexnum-1个顶点w,依次求 v 到 w 的最短路径
{
min=Infinity;
for(w=0;w<c.vexnum ;w++) //在未被访问的顶点中,查找与 v0 最近的顶点v
if(!final[w])
if(d[w]<min) //v0 到 w (有边)的权值<min
{
v=w;
min=d[w];
}//if
final[v]=1; //v 的访问标志设置为1,v 属于s集
for(w=0;w<c.vexnum ;w++) //修改v0 到其余各顶点w 的最短路径权值d[w]
if(!final[w]&&(min+c.arcs[v][w].adj <d[w])) //若w 不属于s,且v 到w 有边相连
{
d[w]=min+c.arcs[v][w].adj; //修改v0 到w 的权值d[w]
for(x=0;x<c.vexnum ;x++) //所有v0 到v 的最短路径上的顶点x,都是v0 到w 的最短路径上的顶点
p[w][x]=p[v][x];
p[w][w]=1;
}//if
}//for
for(v=0;v<c.vexnum ;v++) //输出v0 到其它顶点v 的最短路径
{
if(v!=v0)
printf("%s",c.vexs[v0].name); //输出景点v0 的景点名
for(w=0;w<c.vexnum ;w++) //对图中每个顶点w,试探w 是否是v0 到v 的最短路径上的顶点
{
if(p[v][w] && w!=v0 && w!=v) //若w 是且w 不等于v0,则输出该景点
printf("--->%s",c.vexs[w].name);
}
printf("---->%s",c.vexs[v].name);
printf("\n总路线长为%d米\n\n",d[v]);
}//for
}//shortestpath
//(6)-(11)修改图的信息。包括建图、更新信息、删除、增加结点和边
//(6) 构造图的邻接矩阵
int creatgragh(mgraph &c) //建图。以图的邻接矩阵存储图
{
int i,j,m,n;
int v0,v1;
int distance;
printf("请输入图的顶点数和边数: \n");
scanf("%d %d",&c.vexnum ,&c.arcnum );
printf("下面请输入景点的信息:\n");
for(i=0;i<c.vexnum ;i++) //构造顶点向量(数组)
{
printf("请输入景点的编号:");
scanf("%d",c.vexs[i].position );
printf("\n请输入景点的名称:");
scanf("%s",c.vexs[i].name );
printf("\n请输入景点的简介:");
scanf("%s",c.vexs[i].introction );
}
for(i=0;i<c.arcnum ;i++) //初始化邻接矩阵
for(j=0;j<c.arcnum ;j++)
c.arcs[i][j].adj =Infinity;
printf("下面请输入图的边的信息:\n");
for(i=1;i<=c.arcnum ;i++) //构造邻接矩阵
{
printf("\n第%d条边的起点 终点 长度为:",i);//输入一条边的起点、终点及权值
scanf("%d %d %d",&v0,&v1,&distance);
m=locatevex(c,v0);
n=locatevex(c,v1);
if(m>=0 && n>=0)
{
c.arcs[m][n].adj =distance;
c.arcs[n][m].adj =c.arcs[m][n].adj ;
}
}
return 1;
}//creatgragh
// (7) 更新图的部分信息。返回值: 1
int newgraph(mgraph &c)
{
int changenum; //计数。用于记录要修改的对象的个数
int i,m,n,t,distance,v0,v1;
printf("\n下面请输入你要修改的景点的个数:\n");
scanf("%d",&changenum);
while(changenum<0||changenum>c.vexnum )
{
printf("\n输入错误!请重新输入");
scanf("%d",&changenum);
}
for(i=0;i<changenum;i++)
{
printf("\n请输入景点的编号:");
scanf("%d",&m);
t=locatevex(c,m);
printf("\n请输入景点的名称:");
scanf("%s",c.vexs[t].name );
printf("\n请输入景点的简介:");
scanf("%s",c.vexs[t].introction );
}
printf("\n下面请输入你要更新的边数");
scanf("%d",&changenum);
while(changenum<0||changenum>c.arcnum )
{
printf("\n输入错误!请重新输入");
scanf("%d",&changenum);
}
printf("\n下面请输入更新边的信息:\n");
for(i=1;i<=changenum ;i++)
{
printf("\n修改的第%d条边的起点 终点 长度为:",i);
scanf("%d %d %d",&v0,&v1,&distance);
m=locatevex(c,v0);
n=locatevex(c,v1);
if(m>=0&&n>=0)
{
c.arcs[m][n].adj =distance;
c.arcs[n][m].adj =c.arcs[m][n].adj ;
}
}
return 1;
}//newgraph
⑹ 采用邻接矩阵作为无向图的存储结构
没分还要做那么多,………………
⑺ 无向完全图采用什么存储结构较省空间
邻接矩阵比较好~
凡是边比较多的图,用矩阵相对省一点。。。
⑻ 怎样用邻接矩阵为存储结构创建一个无向图
int CreateUDG(AdjMatrix *G){
int i,j,k,weight;
VertexData v1,v2;
printf("输入图的弧数和顶点数\n");
fflush(stdin);
scanf("%d,%d",&G->arcnum,&G->vexnum); /*输入图的顶点数和弧数*/
for(i=0;i<G->vexnum;i++) /*初始化邻接矩阵*/
for(j=0;j<G->vexnum;j++)
G->arcs[i][j].adj=INFINITY;
for(i=0;i<G->vexnum;i++)
{
printf("输入图的顶点\n");
fflush(stdin);
scanf("%c",&G->vexs[i]); /* 输入图的顶点*/
}
for(k=0;k<G->arcnum;k++)
{
printf("输入一条弧的两个顶点及权值\n");
fflush(stdin);
scanf("%c,%c,%d",&v1,&v2,&weight);/*输入一条弧的两个顶点及权值*/
i=LocateVertex(G,v1);
j=LocateVertex(G,v2);
G->arcs[i][j].adj=weight; /*建立弧*/
}
return(Ok);
}
void main()
{
AdjMatrix G;
CreateDN(&G);
}
⑼ 采用邻接矩阵作为无向图的存储结构,邻接表作为有向图的存储结构,完成无向图和有
YOUdiano~~~~
⑽ 以邻接多重表为存储结构,实现连通无向图的深度优先遍历和广度优先遍历。
没有现成的,自己看看套用一下吧。
邻接多重表
/*********************************************************
Title : graph-multiadjacentlist.c
Author :
Time :
Purpose : 图的多重邻接链表表示法
Thread :
Comment :
Usage :
**********************************************************/
#include "stdio.h"
#include "stdlib.h"
/*=====================变量声明--variable declaration=================*/
struct edge /* 图形边线结构声明 */
{
int vertex1; /* 顶点1资料 */
int vertex2; /* 顶点2资料 */
struct edge *edge1; /* 顶点1下一边线 */
struct edge *edge2; /* 顶点2下一边线 */
};
typedef struct edge *nextedge; /* 图形的边线新型态 */
struct node /* 图形顶点结构宣告 */
{
int vertex; /* 顶点资料 */
struct edge *edge; /* 顶点下一边线 */
};
typedef struct node *graph; /* 图形的结构新型态 */
struct node head[6]; /* 图形顶点结构数组 */
/*=====================函数声明--function declaration=================*/
void creategraph(int *node,int num);
/*====================函数实现--function implementation================*/
/* --------------------------------------------------
Function : void creategraph()
Purpose :
Arguments :
Returns :
------------------------------------------------- */
void creategraph(int *node,int num)
{
nextedge newnode; /* 新边线指标 */
nextedge previous; /* 前一边线指标 */
nextedge ptr; /* 目前边线指标 */
int from; /* 边线的起点 */
int to; /* 边线的终点 */
int i;
for ( i = 0; i < num; i++ ) { /* 读取边线的回路 */
from = node[i*2]; /* 边线的起点 */
to = node[i*2+1]; /* 边线的终点 */
/* 建立新边线记忆体 */
newnode = ( nextedge ) malloc(sizeof(struct edge));
newnode->vertex1 = from; /* 建立顶点内容 */
newnode->vertex2 = to; /* 建立顶点内容 */
newnode->edge1 = NULL; /* 设定指标初值 */
newnode->edge2 = NULL; /* 设定指标初值 */
previous = NULL; /* 前一边线指标 */
ptr = head[from].edge; /* 目前边线指标 */
while ( ptr != NULL ) { /* 遍历到最后边线 */
previous = ptr; /* 保留前一边线 */
if ( ptr->vertex1 == from ) /* 决定走的边线 */
ptr = ptr->edge1; /* 下一边线 */
else
ptr = ptr->edge2; /* 下一边线 */
}
if ( previous == NULL )
head[from].edge = newnode; /* 设定顶点边线指标 */
else
if ( previous->vertex1 == from ) /* 决定走的边线 */
previous->edge1 = newnode; /* 连接下一边线 */
else
previous->edge2 = newnode; /* 连接下一边线 */
previous = NULL; /* 前一边线指标 */
ptr = head[to].edge; /* 目前边线指标 */
while ( ptr != NULL ) { /* 遍历到最后边线 */
previous = ptr; /* 保留前一边线 */
if ( ptr->vertex1 == to ) /* 决定走的边线 */
ptr = ptr->edge1; /* 下一边线 */
else
ptr = ptr->edge2; /* 下一边线 */
}
if ( previous == NULL )
head[to].edge = newnode; /* 设定顶点边线指标 */
else
if ( previous->vertex1 == to ) /* 决定走的边线 */
previous->edge1 = newnode; /* 连接下一边线 */
else
previous->edge2 = newnode; /* 连接下一边线 */
}
}
/*======================主函数--main function--建立图形后,将边线打印出========================*/
int main(int argc, char* argv[])
{
nextedge ptr;
int node[6][2] = { {1, 2}, /* 边线数组 */
{1, 3},
{2, 3},
{2, 4},
{3, 5},
{4, 5}, };
int i;
for ( i = 1; i <= 5; i++ ) {
head.vertex = i; /* 设定顶点值 */
head.edge = NULL; /* 清除图形指标 */
}
creategraph(node,6); /* 建立图形 */
printf("图形的多重邻接链表内容:\n");
for ( i = 1; i <= 5; i++ ) {
printf("顶点%d =>",head.vertex); /* 顶点值 */
ptr = head.edge;
/* 边线位置 */
while ( ptr != NULL ) { /* 遍历至链表尾 */
/* 印出边线 */
printf("(%d,%d)",ptr->vertex1,ptr->vertex2);
/* 决定下一边线指标 */
if ( head.vertex == ptr->vertex1 )
ptr = ptr->edge1; /* 下一个边线 */
else
ptr = ptr->edge2; /* 下一个边线 */
}
printf("\n"); /* 换行 */
}
return 1;
}
// 图的遍历 *
// 生成,深度、广度优先遍历 *
//* * * * * * * * * * * * * * * * * * * * * * * *
#include <dos.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_VERTEX_NUM 20 //图的最大顶点数
#define MAXQSIZE 30 //队列的最大容量
enum BOOL {False,True};
typedef struct ArcNode
{int adjvex; //该弧所指向的顶点的位置
struct ArcNode *nextarc; //指向下一条弧的指针
}ArcNode; //弧结点
typedef struct
{ArcNode* AdjList[MAX_VERTEX_NUM]; //指向第一条依附该顶点的弧的指针
int vexnum,arcnum; //图的当前顶点和弧数
int GraphKind; //图的种类,0---无向图,1---有向图
}Graph;
typedef struct //队列结构
{int elem[MAXQSIZE]; //数据域
int front; //队头指针
int rear; //队尾指针
}SqQueue;
BOOL visited[MAX_VERTEX_NUM]; //全局变量——访问标志数组
void CreateGraph(Graph &); //生成图的邻接表
void DFSTraverse(Graph); //深度优先搜索遍历图
void DFS(Graph,int);
void BFSTraverse(Graph); //广度优先搜索遍历图
void Initial(SqQueue &); //初始化一个队列
BOOL QueueEmpty(SqQueue); //判断队列是否空
BOOL EnQueue(SqQueue &,int); //将一个元素入队列
BOOL DeQueue(SqQueue &,int &); //将一个元素出队列
int FirstAdjVex(Graph,int); //求图中某一顶点的第一个邻接顶点
int NextAdjVex(Graph,int,int); //求某一顶点的下一个邻接顶点
void main()
{Graph G; //采用邻接表结构的图
char j='y';
//------------------程序解说----------------------------
printf("本程序将演示生成一个图,并对它进行遍历.
");
printf("首先输入要生成的图的种类.
");
printf("0---无向图, 1--有向图
");
printf("之后输入图的顶点数和弧数。
格式:顶点数,弧数;例如:4,3
");
printf("接着输入各边(弧尾,弧头).
例如:
1,2
1,3
2,4
");
printf("程序会生成一个图,并对它进行深度和广度遍历.
");
printf("深度遍历:1->2->4->3
广度遍历:1->2->3->4
");
//------------------------------------------------------
while(j!='N'&&j!='n')
{printf("请输入要生成的图的种类(0/1):");
scanf("%d",&G.GraphKind); //输入图的种类
printf("请输入顶点数和弧数:");
scanf("%d,%d",&G.vexnum,&G.arcnum); //输入图的顶点数和弧数
CreateGraph(G); //生成邻接表结构的图
DFSTraverse(G); //深度优先搜索遍历图
BFSTraverse(G); //广度优先搜索遍历图
printf("图遍历完毕,继续进行吗?(Y/N)");
scanf(" %c",&j);
}
}
void CreateGraph(Graph &G)
{//构造邻接表结构的图G
int i;
int start,end;
ArcNode *s;
for(i=1;i<=G.vexnum;i++) G.AdjList=NULL; //初始化指针数组
for(i=1;i<=G.arcnum;i++)
{scanf("%d,%d",&start,&end); //输入弧的起点和终点
s=(ArcNode *)malloc(sizeof(ArcNode)); //生成一个弧结点
s->nextarc=G.AdjList[start]; //插入到邻接表中
s->adjvex=end;
G.AdjList[start]=s;
if(G.GraphKind==0) //若是无向图,再插入到终点的弧链中
{s=(ArcNode *)malloc(sizeof(ArcNode));
s->nextarc=G.AdjList[end];
s->adjvex=start;
G.AdjList[end]=s;
}
}
}
void DFSTraverse(Graph G)
{//深度优先遍历图G
int i;
printf("DFSTraverse:");
for(i=1;i<=G.vexnum;i++) visited=False; //访问标志数组初始化
for(i=1;i<=G.vexnum;i++)
if(!visited) DFS(G,i); //对尚未访问的顶点调用DFS
printf("\b\b
");
}
void DFS(Graph G,int i)
{//从第i个顶点出发递归地深度遍历图G
int w;
visited=True; //访问第i个顶点
printf("%d->",i);
for(w=FirstAdjVex(G,i);w;w=NextAdjVex(G,i,w))
if(!visited[w]) DFS(G,w); //对尚未访问的邻接顶点w调用DFS
}
void BFSTraverse(Graph G)
{//按广度优先非递归的遍历图G,使用辅助队列Q和访问标志数组visited
int i,u,w;
SqQueue Q;
printf("BFSTreverse:");
for(i=1;i<= G.vexnum;i++) visited=False; //访问标志数组初始化
Initial(Q); //初始化队列
for(i=1;i<=G.vexnum;i++)
if(!visited)
{visited=True; //访问顶点i
printf("%d->",i);
EnQueue(Q,i); //将序号i入队列
while(!QueueEmpty(Q)) //若队列不空,继续
{DeQueue(Q,u); //将队头元素出队列并置为u
for(w=FirstAdjVex(G,u);w;w=NextAdjVex(G,u,w))
if(!visited[w]) //对u的尚未访问的邻接顶点w进行访问并入队列
{visited[w]=True;
printf("%d->",w);
EnQueue(Q,w);
}
}
}
printf("\b\b
");
}
int FirstAdjVex(Graph G,int v)
{//在图G中寻找第v个顶点的第一个邻接顶点
if(!G.AdjList[v]) return 0;
else return(G.AdjList[v]->adjvex);
}
int NextAdjVex(Graph G,int v,int u)
{//在图G中寻找第v个顶点的相对于u的下一个邻接顶点
ArcNode *p;
p=G.AdjList[v];
while(p->adjvex!=u) p=p->nextarc; //在顶点v的弧链中找到顶点u
if(p->nextarc==NULL) return 0; //若已是最后一个顶点,返回0
else return(p->nextarc->adjvex); //返回下一个邻接顶点的序号
}
void Initial(SqQueue &Q)
{//队列初始化
Q.front=Q.rear=0;
}
BOOL QueueEmpty(SqQueue Q)
{//判断队列是否已空,若空返回True,否则返回False
if(Q.front==Q.rear) return True;
else return False;
}
BOOL EnQueue(SqQueue &Q,int ch)
{//入队列,成功返回True,失败返回False
if((Q.rear+1)%MAXQSIZE==Q.front) return False;
Q.elem[Q.rear]=ch;
Q.rear=(Q.rear+1)%MAXQSIZE;
return True;
}
BOOL DeQueue(SqQueue &Q,int &ch)
{//出队列,成功返回True,并用ch返回该元素值,失败返回False
if(Q.front==Q.rear) return False;
ch=Q.elem[Q.front];
Q.front=(Q.front+1)%MAXQSIZE;
return True; //成功出队列,返回True
}
转载