考研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