#include <stdio.h>
#include <stdlib.h>
#define MAX 20
// 有向网的建立 深度遍历 广度遍历等操作的实现
typedef struct ArcNode
{
int adjvex;
int weight;
struct ArcNode *next;
}ArcNode;
typedef struct VertexNode
{
char vexdata;
ArcNode *head;
}VertexNode;
typedef struct
{
VertexNode vertex[MAX];
int vexnum;
int arcnum;
}AdjList;
typedef struct Node{
int data[MAX];
int front;
int order;
}Queue;
void Creat(AdjList *G)
{
int i,weight,vex1,vex2;
ArcNode *q=NULL;
printf(“请输入有向网中的顶点数和边数:”);
scanf(“%d,%d”,&G->vexnum,&G->arcnum);
getchar();
for(i=1;i<=G->vexnum;i++)
{
printf(“请输入第%d个结点的名称:”,i);
scanf(“%c”,&G->vertex[i].vexdata);
getchar();
G->vertex[i].head=NULL;
}
for(i=1;i<=G->arcnum;i++)
{
printf(“请输入第%d条边的起点和终点以及权值:”,i);
scanf(“%d,%d,%d”,&vex1,&vex2,&weight);
q=(ArcNode *)malloc(sizeof(ArcNode));
q->adjvex=vex2;
q->weight=weight;
q->next=G->vertex[vex1].head;
G->vertex[vex1].head=q;
}
}
int visited[MAX];
//深度优先遍历
void DFS(AdjList *G,int i)
{
ArcNode *p;
visited[i]=1; //设置下标为I的顶点为已访问
printf(“%c “,G->vertex[i].vexdata); //输出顶点信息
p = G->vertex[i].head; //下一个边表结点
while(p)
{
if(!visited[p->adjvex]) //如果是未访问的则递归
DFS(G,p->adjvex);
p=p->next;
}
}
void DFSTraverse(AdjList *G)
{ int i;
for(i=1;i<=G->vexnum;i++) //初始化每个顶点都未访问过
visited[i] = 0;
for(i=1;i<=G->vexnum;i++) //选取一个未访问的顶点,进行深度优先搜索,
{
if(visited[i]!=1) //如果是连通图只执行一次
DFS(G,i);
}
}
//广度优先遍历
void InitQueue(Queue *q)
{
q->front = q->order = 0;
memset(q->data,-1,sizeof(int)*MAX);
}
int IsEmpty(Queue *q)
{
if(q->order == q->front)
return 1;
return 0;
}
void EnQueue(Queue *q,int Element)
{
if((q->order + 1) % MAX == q->front)
return;
q->data[q->order] = Element;
q->order = (q->order + 1) / MAX;
}
void DeQueue(Queue *q,int *e)
{
if(q->order == q->front)
return;
*e = q->data[q->front];
q->front = (q->front + 1) % MAX;
}
void BFSTraverse(AdjList *G)
{
int i;
Queue q;
ArcNode *p;
InitQueue(&q); //初始化队列
for(i=1;i<=G->vexnum;i++) //设置所为顶点为未访问
visited[i]=0;
for(i=1;i<=G->vexnum;i++)
{
if(!visited[i]) //选取一个未访问的顶点,如果图是连通图,则只执行一次
{
visited[i]=1; //设置顶点为已访问
printf(“%c “,G->vertex[i].vexdata);
EnQueue(&q,i); //当前顶点的下标值进队
while(IsEmpty(&q)!=1) //队列不为空
{
DeQueue(&q,&i); //出队
p = G->vertex[i].head; //指向下一个边表结点
while(p)
{
if(!visited[p->adjvex]) //如果是未访问的结点
{
visited[p->adjvex]=1;
printf(“%c “,G->vertex[p->adjvex].vexdata);
EnQueue(&q,p->adjvex);
}
p=p->next; //指向下一个边表结点
}
}
}
}
}
void DisplayGraph(AdjList *adj)
{
int i;
int n=adj->vexnum;//顶点个数,后面要遍历每一个点点
ArcNode *q=NULL;
for( i=1;i<=n;i++)
{
q=adj->vertex[i].head;
if(q==NULL)//表示头结点后面没有跟其他结点
{
printf(“没有从%c出发的节点\n”,adj->vertex[i].vexdata);
}
else
{
printf(“从结点%c出发的边有:”,adj->vertex[i].vexdata);
while(q!=NULL)
{
printf(“%c–>%c\n”,adj->vertex[i].vexdata,adj->vertex[q->adjvex].vexdata);
q=q->next;
}
}
}
}
void main()
{
AdjList *G=(AdjList *)malloc(sizeof(AdjList));
Creat(G);
DisplayGraph(G);
printf(“深度优先搜索遍历:\n”);
DFSTraverse(G);
printf(“\n”);
printf(“广度优先搜索遍历:\n”);
BFSTraverse(G);
}