其他分享
首页 > 其他分享> > 考研C语言数据结构-图(图的邻接表实现 + 广度、深度优先遍历)

考研C语言数据结构-图(图的邻接表实现 + 广度、深度优先遍历)

作者:互联网

图的结构如下:

图的邻接表实现 + 广度(BFS)、深度(DFS)优先遍历:

#include <stdio.h>
#include <stdlib.h>

#define MAXVEXNUM 10

// 定义边表结点存储结构
struct ArcNode {

	int adjvex; // 邻接顶点
	struct ArcNode *next; // 下一邻接顶点
};

// 定义顶点表结点存储结构
struct VNode {

	int vex; // 顶点信息
	struct ArcNode *next; // 顶点的下一邻接点结点信息
};

// 定义邻接表存储结构
struct ALGraph {

	VNode VNodeArray[MAXVEXNUM]; // 邻接表
	int vexNum, arcNum;
};

// 初始化邻接表
void initALGraph(ALGraph &G) {

	G.vexNum = 8;

	for(int i = 0;i < G.vexNum;i++) {
	
		G.VNodeArray[i].vex = i + 1;

	}

	G.arcNum = 10;

	// 定义v1顶点领边单链表
	ArcNode* v1_2 = (ArcNode *)malloc(sizeof(ArcNode));
	v1_2->adjvex = 2, v1_2->next = NULL;
	G.VNodeArray[0].next = v1_2;

	ArcNode* v1_5 = (ArcNode *)malloc(sizeof(ArcNode));
	v1_5->adjvex = 5, v1_5->next = NULL;
	v1_2->next = v1_5;


	// 定义v5顶点领边单链表
	ArcNode* v5_1 = (ArcNode *)malloc(sizeof(ArcNode));
	v5_1->adjvex = 1, v5_1->next = NULL;
	G.VNodeArray[4].next = v5_1;


	// 定义v2顶点领边单链表
	ArcNode* v2_1 = (ArcNode *)malloc(sizeof(ArcNode));
	v2_1->adjvex = 1, v2_1->next = NULL;
	G.VNodeArray[1].next = v2_1;

	ArcNode* v2_6 = (ArcNode *)malloc(sizeof(ArcNode));
	v2_6->adjvex = 6, v2_6->next = NULL;
	v2_1->next = v2_6;


	// 定义v6顶点领边单链表
	ArcNode* v6_2 = (ArcNode *)malloc(sizeof(ArcNode));
	v6_2->adjvex = 2, v6_2->next = NULL;
	G.VNodeArray[5].next = v6_2;

	ArcNode* v6_3 = (ArcNode *)malloc(sizeof(ArcNode));
	v6_3->adjvex = 3, v6_3->next = NULL;
	v6_2->next = v6_3;

	ArcNode* v6_7 = (ArcNode *)malloc(sizeof(ArcNode));
	v6_7->adjvex = 7, v6_7->next = NULL;
	v6_3->next = v6_7;


	// 定义v3顶点领边单链表
	ArcNode* v3_4 = (ArcNode *)malloc(sizeof(ArcNode));
	v3_4->adjvex = 4, v3_4->next = NULL;
	G.VNodeArray[2].next = v3_4;

	ArcNode* v3_6 = (ArcNode *)malloc(sizeof(ArcNode));
	v3_6->adjvex = 6, v3_6->next = NULL;
	v3_4->next = v3_6;

	ArcNode* v3_7 = (ArcNode *)malloc(sizeof(ArcNode));
	v3_7->adjvex = 7, v3_7->next = NULL;
	v3_6->next = v3_7;


	// 定义v7顶点领边单链表
	ArcNode* v7_3 = (ArcNode *)malloc(sizeof(ArcNode));
	v7_3->adjvex = 3, v7_3->next = NULL;
	G.VNodeArray[6].next = v7_3;

	ArcNode* v7_4 = (ArcNode *)malloc(sizeof(ArcNode));
	v7_4->adjvex =4, v7_4->next = NULL;
	v7_3->next = v7_4;

	ArcNode* v7_6 = (ArcNode *)malloc(sizeof(ArcNode));
	v7_6->adjvex = 6, v7_6->next = NULL;
	v7_4->next = v7_6;


	// 定义v4顶点领边单链表
	ArcNode* v4_3 = (ArcNode *)malloc(sizeof(ArcNode));
	v4_3->adjvex = 3, v4_3->next = NULL;
	G.VNodeArray[3].next = v4_3;

	ArcNode* v4_7 = (ArcNode *)malloc(sizeof(ArcNode));
	v4_7->adjvex = 7, v4_7->next = NULL;
	v4_3->next = v4_7;

	ArcNode* v4_8 = (ArcNode *)malloc(sizeof(ArcNode));
	v4_8->adjvex = 8, v4_8->next = NULL;
	v4_7->next = v4_8;


	// 定义v8顶点领边单链表
	ArcNode* v8_4 = (ArcNode *)malloc(sizeof(ArcNode));
	v8_4->adjvex = 4, v8_4->next = NULL;
	G.VNodeArray[7].next = v8_4;

	ArcNode* v8_7 = (ArcNode *)malloc(sizeof(ArcNode));
	v8_7->adjvex = 7, v8_7->next = NULL;
	v8_4->next = v8_7;
}

// 广度优先遍历
// 定义队列数据结构
// 定义结点数据类型
typedef struct LNode {

	VNode data;
	struct LNode *next;
}LNode;

// 定义链队数据类型
typedef struct {

	LNode *front, *rear;
}LiQueue;

void initLiQueue(LiQueue &Q) {

	Q.front = Q.rear = (LNode *)malloc(sizeof(LNode));
	Q.front->next = NULL;
}

// 判断队列空
bool isEmpty(LiQueue Q) {

	if(Q.front == Q.rear)
		return true;

	return false;
}

// 入队操作
void enQueue(LiQueue &Q, VNode e) {

	LNode *p = (LNode *)malloc(sizeof(LNode));

	p->data = e;

	p->next = NULL;

	Q.rear->next = p;

	Q.rear = p;
}

// 出队操作
bool deQueue(LiQueue &Q, VNode &e) {

	if(isEmpty(Q))
		return false;

	LNode *p = Q.front->next;

	e = p->data;

	Q.front->next = p->next;

	// 如果出队元素是队列的最后一个元素,需要修改尾指针
	if(p == Q.rear)
		Q.rear = Q.front;

	free(p);

	return true;
}

// 定义访问数组,标记已访问顶点
bool visited[MAXVEXNUM];

// 根据顶点的相邻结点单链表中结点获取对应顶点结点信息
VNode getCorrespondingVNode(ALGraph G, ArcNode *p) {

	return G.VNodeArray[p->adjvex - 1]; // // -1因为数组是从0开始的,而顶点从1开始
}

// 获取顶点v的第一个相邻顶点
ArcNode* getFirstNeighbor(ALGraph G, VNode v) {

	return v.next;
}

// 获取顶点v除顶点u之外的相邻顶点
ArcNode* getNextNeighbor(ALGraph G, ArcNode* u) {

	return u->next;
}

void BFS(ALGraph G, VNode v, LiQueue &Q) {

	printf("广度优先遍历顶点:%d\n", v.vex);
	visited[v.vex - 1] = true;
	enQueue(Q, v);

	while(!isEmpty(Q)) {
	
		deQueue(Q, v);
		for(ArcNode* w = getFirstNeighbor(G, v);w != NULL;w = getNextNeighbor(G, w)) {

			VNode n = getCorrespondingVNode(G, w);
			if(!visited[n.vex - 1]) {
			
				printf("广度优先遍历顶点:%d\n", n.vex);
				visited[n.vex - 1] = true;
				enQueue(Q, n);
			}
		}
	}
}

void BFSTraverse(ALGraph G) {

	for(int i = 0;i < G.vexNum;i++) {
	
		visited[i] = false;
	}

	LiQueue Q;
	initLiQueue(Q);

	for(int i = 0;i < G.vexNum;i++) {
	
		if(!visited[i])
			BFS(G, G.VNodeArray[i], Q);
	}
}

// 深度优先遍历
void DFS(ALGraph G, VNode v) {

	printf("深度优先遍历顶点:%d\n", v);
	visited[v.vex - 1] = true;

	for(ArcNode* w = getFirstNeighbor(G, v);w != NULL;w = getNextNeighbor(G, w)) {
	
		if(!visited[w->adjvex - 1]) {
		
			DFS(G, getCorrespondingVNode(G, w));
		}
	}
}

void DFSTravse(ALGraph G) {

	for(int i = 0;i < G.vexNum;i++) {
	
		visited[i] = false;
	}

	for(int i = 0;i < G.vexNum;i++) {
	
		if(!visited[i])
			DFS(G, G.VNodeArray[i]);
	}
}

int main(void) {

	ALGraph G;
	initALGraph(G);

	BFSTraverse(G);

	printf("\n");

	DFSTravse(G);
	system("pause");
	return 0;
}

标签:malloc,遍历,C语言,next,adjvex,ArcNode,sizeof,NULL,考研
来源: https://www.cnblogs.com/dqlai/p/16353040.html