#include <stdlib.h> /*引用两个头文件*/
#include <stdio.h>
#include <malloc.h>
#include <conio.h>
#include <string.h>
#define maxvex 30 /*定义MAXVEX=30*/
struct edgenode /*定义边的结构体(边结点类型)*/
{int adjvex; /*存放关联顶点的下标号*/
char info[10]; /*存放关联顶点的数据(字符串),c语言中字符串用数组表示*/
int weight; /*边上的权值*/
struct edgenode*next; /*存放下一个边结点的地址*/
};
struct vexnode /*定义顶点的结构体(表头结点类型)*/
{char data[10]; /*存放顶点的数据(字符串),c语言中字符串用数组表示*/
struct edgenode *link; /*存放边链表的头指针*/
};
typedef struct vexnode adjlist[maxvex]; /*自定义adjlist为结构体数组类型(顶点表数组类型)*/
adjlist tu1; /*定义结构体数组变量tu1 (顶点表数组)*/
void creategraph(adjlist g,int n) /*创建图函数*/
{int e,i,s,d,w; /*定义存储边、点的变量*/
struct edgenode *p,*q; /*定义指向边结点的指针*/
printf("输入图的顶点数point(n)和边数edge(e)(用逗号隔开):"); /*显示提示输入图的顶点、边的数量*/
scanf("%d,%d",&n,&e); /*接收图的点、边存入n,e中*/
for(i=1;i<=n;i++) /*用循环接收各顶点信息,并存入表头结点表,从下标1开始*/
{getchar();
printf("\n the %d information:",i); /*提示输入结点信息*/
scanf("%s",&g[i].data); /*存储信息*/
g[i].link=NULL; /*链指针初始为空*/
}
printf("\n输入各边关联的两顶点的序号及权值,分别用逗号隔开:\n");
for(i=1;i<=e;i++) /*用循环接收各边信息,并存入各头结点对应的边链表。因是无向图,每次添加两个边结点,分别插入对应的两个链队*/
{printf("\n第 %d 条边的信息=>\n\t :",i); /*提示输入边信息*/
scanf("%d,%d,%d",&s,&d,&w); /*接收边的信息,s和d为边关联的两个结点的下标,w为权值*/
p=(struct edgenode*)malloc(sizeof(struct edgenode)); /*新建一个边结点,用P指向*/
q=(struct edgenode*)malloc(sizeof(struct edgenode)); /*新建一个边结点,用q指向*/
p->adjvex=d; /*把其中一个点存储下来*/
strncpy( p->info, g[d].data, sizeof(g[d].data)); /*数组间(字符串)赋值用此语句*/
p->weight=w;
q->adjvex=s; /*把另一个点存储下来*/
strncpy( q->info, g[s].data, sizeof(g[s].data)); /*数组间(字符串)赋值用此语句*/
q->weight=w;
p->next=g[s].link; /*p所指结点插入下标为s的头结点的边链表,头插法*/
g[s].link=p;
q->next=g[d].link; /*q所指结点插入下标为d的头结点的边链表,头插法*/
g[d].link=q;
/*完成一个边的创建*/
}
}
int visited[maxvex]; /*定义访问数组*/
void dfs(adjlist adj,int v) /*深度优先遍历函数,从第v个顶点出发遍历图adj*/
{int i;
struct edgenode *p; /*定义边指针*/
visited[v]=1; /*把开始遍历的点在访问数组中标识为1*/
printf("now is at point %d ,",v); /*输出正访问的点*/
p=adj[v].link; /*P指向下标为v的头结点的边链表(p指向v的第1个邻接点)*/
printf("the data is %s \n", adj[v].data); /*输出点v的信息*/
getch();
while(p) /*只要当前邻接点非空*/
{if( visited[p->adjvex] == 0) /*如果当前邻接点未被访问过*/
dfs(adj,p->adjvex); /*递归调用DFS函数,对当前邻接点进行遍历*/
p=p->next; /*若当前邻接点被访问过,p指向下一个,继续判断*/
}
}
int quene[maxvex]; /*定义一个队列,用于广度优先遍历*/
void bfs(adjlist adj,int vi) /*广度优先遍历图,从vi顶点开始*/
{int m=maxvex; /*m为队列元素个数*/
int front=0, rear=1, v; /*定义队列的头指针、尾指针及其初值,定义v暂存出队的顶点*/
struct edgenode *p; /*定义边指针*/
visited[vi]=1; /*开始访问的点标识一下*/
printf("now visit the point:%d,the data is %s\n",vi,adj[vi].data); /*输出正访问的点*/
getch();quene[rear]=vi; /*把访问过的点放入队列中*/
while(front!=rear)
{front=(front+1)%m;
v=quene[front]; /*队首元素(出队顶点的下标号)出队,暂存于v*/
p= adj[v].link; /*p指向出队顶点的第一个邻接点*/
while(p) /*只要邻接点非空*/
{if(visited[p->adjvex]==0) /*判断当前邻接点p->adjvex点是否访问过*/
{visited[p->adjvex]=1; /*访问没有访问过的结点*/
printf("now visit the point:%d,the data is %s\n",p->adjvex,p->info); /*输出正访问的邻接点的下标、城市名*/
getch();
rear=(rear+1)%m; /*尾指针后移*/
quene[rear]=p->adjvex; /*将当前访问的顶点下标放入队列中*/
}
p=p->next; /*p指向下一个邻接点*/
}
}
}
void main()
{int i;
// clrscr(); /*清屏函数*/
creategraph(tu1,0); /*创建图*/
for(i=1;i<maxvex;i++)
visited[i]=0; /*访问数组初始化取值0*/
printf("\n深度优先遍历如下:\n");
dfs(tu1,1); /*深度优先遍历图,从1顶点起始*/
getch(); /*等待输入*/
for(i=1;i<maxvex;i++)
visited[i]=0; /*调用BFS前,将访问数组初始化为0*/
printf("\n广度优先遍历如下:\n");
bfs(tu1,1); /*广度优先遍历图,从1顶点起始*/
}