图的邻接表的创建与遍历

图的邻接表的创建、深度优先遍历和广度优先遍历

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);
}

结果:
《图的邻接表的创建与遍历》

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/asd_wolf/article/details/9106465
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞