这里用的是邻接表表示法,邻接表不清楚的自行百度一下。 先上输出的结果:
head代表节点,->edge代表head->edge两节点的边,weight代表权重。可以根据图的节点和边的关系画出图的形状。
#include <stdio.h>
#include <stdlib.h>
#define max 100
int visited[max]={0,};
typedef int vex;
typedef struct edge{
vex vertex; //对应边
struct edge *next;//边指向下一个节点
int weight; //路径的权重
}edgenode;
typedef struct vnode{
edgenode *firstedge; //指向的第一个节点
vex head; //头结点的值
}Adjlist[max]; //这是一个指针数组,数组里面存的是头结点
typedef struct {
Adjlist adjlist;
int nv,ne;
}graph; //这个是图,里面v,e对应边的数量。adjlist是指针数组
graph *buildGraph() //创建一个图返回
{ //用队列来存边a,边b,权重
int queue[]={0,1,1,1,2,4,1,4,2,2,4,1,2,5,1,1,3,1,1,7,3,3,5,3,3,6,2,6,7,1,};
int front=0,rear=sizeof(queue)/sizeof(queue[0]);
graph *g=(graph *)malloc(sizeof(graph));
g->ne=10; //边的个数
g->nv=8; //顶点个数
int v1,v2,w;
for(int v=0;v<g->nv;v++)
{
g->adjlist[v].firstedge=NULL; //图的第一条边都指向NULL
g->adjlist[v].head=v; //图的head都为v,v是0-7,队列中的图的定点也是0-7
}
for(int e=0;e<g->ne;e++)
{
v1=queue[front++]; //v1是边a
v2=queue[front++]; //v2是边b
w=queue[front++]; //w是权重
edgenode *e1=(edgenode *)malloc(sizeof(edgenode)); //创建一条边
e1->vertex=v1; //边的vertex=v1
e1->weight=w; //权重
e1->next=g->adjlist[v2].firstedge; //这里是单链表的头插法,把e1插在v2顶点的第一条边上
g->adjlist[v2].firstedge=e1; //这里将v2顶点的第一条边指向e1
edgenode *e2=(edgenode *)malloc(sizeof(edgenode)); //创建一条边
e2->vertex=v2; //这里和上面一样
e2->weight=w;
e2->next=g->adjlist[v1].firstedge;
g->adjlist[v1].firstedge=e2;
}
return g;
}
void PrintGraph(graph *g)
{
edgenode *e;
for(int i=0;i<g->nv;i++)
{
printf("H:%d",g->adjlist[i].head);
for(e=g->adjlist[i].firstedge;e!=NULL;e=e->next)
{
printf("E:%d(W:%d)->",e->vertex,e->weight);
}
printf("\n");
}
}
void DFS(graph *g,int v)
{
edgenode *e;
visited[v]=1; //当图的节点被访问了设置为1
printf("%d->",g->adjlist[v].head);//输出节点
for(e=g->adjlist[v].firstedge;e!=NULL;e=e->next)
{
if(visited[e->vertex]!=1) //这里如果e->vertex没有被访问,递归进去访问e->vertex
{
DFS(g,e->vertex);
}
}
}
void BFS(graph *g,int v)
{
edgenode *e;
int queue[max]; //创建队列
int front=0,rear=0;
visited[v]=8; //访问节点v
printf("%d->",g->adjlist[v].head);
queue[rear++]=g->adjlist[v].head; //加进队列
while(front!=rear)
{
v=queue[front++]; //出队
for(e=g->adjlist[v].firstedge;e!=NULL;e=e->next) //从v开始遍历邻接表后面的节点
{
if(visited[e->vertex]!=8) //没有访问过
{
visited[e->vertex]=8; //标记一下访问了
printf("%d->",e->vertex); //访问输出
queue[rear++]=e->vertex; //加进队列,然后下一轮出队循环
}
}
}
}
int main()
{
graph *g=buildGraph();
PrintGraph(g); //打印图
int v=0;
printf("\n深度优先遍历为:\n");
DFS(g,v);
printf("\n广度优先遍历为:\n");
BFS(g,v);
}