图的邻接表的创建、深度优先遍历和广度优先遍历
1.邻接表的定义
#define NUM 8
typedef int vex;
typedef struct __ArcNode
{
int adjvex;
struct __ArcNode *nextarc;
}ArcNode;
typedef struct __VNode
{
vex data;
ArcNode *firstarc;
}VNode;
2.图邻接表的创建、销毁与显示
status CreateGraph(VNode *AdjList)
{
int i;
int c;
ArcNode **p;
for(i = 0; i < NUM; i++)//1 2 3 4 5
{
AdjList[i].data = 1 + i;
}
for(i = 0; i < NUM; i++)
{
printf("输入以%d为尾的弧(0为结束):", AdjList[i].data);
p = &AdjList[i].firstarc;
scanf("%d", &c);
while(c != 0)
{
*p = (ArcNode *)malloc(sizeof(ArcNode));
(*p)->adjvex = c - 1;//坐标是从0开始的,所以要减去1
p = &(*p)->nextarc;
scanf("%d", &c);
}
*p = NULL;
}
return TRUE;
}
status DestroyGraph(VNode *adj)
{
int i;
ArcNode *p, *pt;
for(i = 0; i < NUM; i++)
{
p = adj[i].firstarc;
while(p)
{
pt = p->nextarc;
free(p);
p = pt;
}
}
return TRUE;
}
void PrintGragh(VNode *adj)
{
int i;
ArcNode *p;
for(i = 0; i < NUM; i++)
{
p = adj[i].firstarc;
while(p)
{
printf("%d->%d\n", adj[i].data, adj[p->adjvex].data);
p = p->nextarc;
}
}
}
3.获得邻接点
ArcNode *FirstAdjVex(VNode *adj, vex v)
{
int i;
i = v - 1;
return adj[i].firstarc;
}
ArcNode *NextAdjVex(VNode *adj, vex v, vex w)
{
int i;
ArcNode *p;
i = v - 1;
p = adj[i].firstarc;
while(p)
{
if(adj[p->adjvex].data == w)//找到w的下一个节点
{
break;
}
else
{
p = p->nextarc;
}
}
if(p != NULL)
{
p = p->nextarc;
}
return p;
}
4.深度优先遍历
void visitNode(VNode *adj, vex n)
{
printf("%d ", adj[n - 1].data);
}
int vexflag[NUM];
status DFS(VNode *adj, vex n, void (*visit)(VNode *adj, vex n))
{
ArcNode *p;
vex m;
visit(adj, n);//访问顶点n
vexflag[n - 1] = 1;
for(p = FirstAdjVex(adj, n); p != NULL; p = NextAdjVex(adj, n, m))
{
m = adj[p->adjvex].data;
if(vexflag[m - 1] == 0)
{
DFS(adj, m, visit);
}
}
return TRUE;
}
status DFSTraverse(VNode *adj, void (*visit)(VNode *adj, vex n))
{
int i;
for(i = 0; i < NUM; i++)
{
vexflag[i] = 0;
}
for(i = 0; i < NUM; i++)
{
if(vexflag[i] == 0)
{
DFS(adj, i + 1, visit);
}
}
return TRUE;
}
5.广度优先遍历
利用队列实现图的广度优先遍历,队列的基本操作参见:
status BFSTraverse(VNode *adj, void (*visit)(VNode *adj, vex n))
{
int i;
vex n;
vex m;
ArcNode *p;
queue q;
for(i = 0; i < NUM; i++)
{
vexflag[i] = 0;
}
initqueue(&q);
for(i = 0; i < NUM; i++)
{
if(vexflag[i] == 0)
{
visit(adj, i + 1);
vexflag[i] = 1;
enqueue(&q, i + 1);
while(!IsEmptyQueue(&q))
{
dequeue(&q, &n);
for(p = FirstAdjVex(adj, n); p != NULL; p = NextAdjVex(adj, n, m))
{
m = adj[p->adjvex].data;
if(vexflag[m - 1] == 0)
{
visit(adj, m);
vexflag[m - 1] = 1;
enqueue(&q, m);
}
}
}
}
}
destroyqueue(&q);
}
6.测试
int main()
{
VNode AdjList[NUM];
ArcNode *p;
// freopen("1.txt", "r", stdin);
CreateGraph(AdjList);
printf("\n");
PrintGragh(AdjList);
p = NextAdjVex(AdjList, 1, 2);
printf("%d\n", AdjList[p->adjvex].data);
DFSTraverse(AdjList, visitNode);
printf("\n");
BFSTraverse(AdjList, visitNode);
printf("\n");
DestroyGraph(AdjList);
}
结果: