typedef struct ArcNode {
int adjvex; // 该边所指向的顶点的序号
struct ArcNode *nextarc; // 指向下一条边的指针
int weight; // 边的权值
} ArcNode; // 弧边的节点结构
typedef struct {
int data; // 顶点信息
int inDegree; // 顶点的入度
ArcNode *firstarc; // 指向第一条依附该点的边的指针
} AdjList[5]; // 定点的节点结构
typedef struct {
AdjList adjList; //
int vexnum, arcnum; // 图当前的顶点数和边数
} Graph;//图的结构定义
bool visited[5] = {false, false, false, false, false}; //标记已经访问过的节点
/**
* 深度优先遍历 递归
* @param g
* @param v
*/
void G_DFS(Graph *g, int v) {
printf("%d ", g->adjList[v].data); // 访问顶点v
visited[v] = true; // 标记已经访问过
ArcNode *arc = g->adjList[v].firstarc; // 记录第一个链接节点
while (arc) {
int adjvex = arc->adjvex; // 拿取顶点所在的序号值
if (!visited[adjvex]) { // 没有访问过
G_DFS(g, adjvex); // 深度 递归访问
}
arc = arc->nextarc; // 拿取下一个链接节点
}
}
/**
* 深度优先算法 非递归
* @param g
*/
void G_DFS_N(Graph *g) {
Stack *stack = NULL;
stack = initStack(stack); // 初始化栈
enStack(stack, g->adjList[0].data); // 放入起始节点
ArcNode *arc = NULL; // 用于标记第一个链接点
while (!isEmptyStack(stack)) { // 栈为空时,则退出,说明已经全部访问完
int vex = deStack(stack); // 出栈,
visited[vex] = true;
printf("%4d", vex);
arc = g->adjList[vex].firstarc; // 拿取链接的第一个节点
while (arc) {
if (!visited[arc->adjvex]) {
enStack(stack, arc->adjvex); // 没有访问则放入栈中
}
arc = arc->nextarc;
}
}
}
/**
* 广度优先遍历 非递归
* @param g
*/
void G_BFS_N(Graph *g) {
Queue *queue = NULL;
queue = initQueue(queue); // 初始化队列
enQueue(queue, g->adjList[0].data); // 起始节点入队
ArcNode *arc = NULL;
while (!isNULLQueue(queue)) { // 队列为空时,退出
int vex = deQueue(queue); // 出队
visited[vex] = true;
printf("%4d", vex);
arc = g->adjList[vex].firstarc;
while (arc) {
if (!visited[arc->adjvex]) { // 没有访问过则入队
enQueue(queue, arc->adjvex);
}
arc = arc->nextarc;
}
}
}
/**
* 查找到 k 到 v 的所有简单路径
* i 表示path的下标,用于回溯操作
* @return
*/
void searchKToVPathByDFS(Graph *g, int k, int v, int path[], int i) {
path[i++] = g->adjList[k].data; // 路径放入
if (g->adjList[k].data == g->adjList[v].data) { // 说明找到一个简单路径,输出结果
for (int l = 0; l < i; ++l) {
printf("%4d", path[l]);
}
printf("\n");
return;
}
visited[k] = true; // 标记已经访问
ArcNode *arc = g->adjList[k].firstarc;
while (arc) {
int adjvex = arc->adjvex;
if (!visited[adjvex]) { // 没有访问过
searchKToVPathByDFS(g, adjvex, v, path, i); // 递归查找
}
// i 不用--,因为当前的i值并没有变化,相当于回溯操作
arc = arc->nextarc;
}
}
/**
* 求顶点v的入度
* 只需要遍历顶点链表的每一行,只要nextarc==v就是入度
* @return
*/
int calculateImportDegree(Graph *g, int v, int n) {
ArcNode *arc = NULL;
for (int i = 0; i < g->vexnum; ++i) {
arc = g->adjList[i].firstarc;
while (arc) {
if (arc->adjvex == v) {
++n;
}
arc = arc->nextarc;
}
}
return n;
}
/**
* 求度最大的节点
* @param g
*/
void calculateMaxDegree(Graph *g) {
int maxVex = 0, max, nowVex;
ArcNode *arc = NULL;
for (int i = 0; i < g->vexnum; ++i) {
arc = g->adjList[i].firstarc;
nowVex = 0;
while (arc) { // 求出度
nowVex++;
arc = arc->nextarc;
}
int importDegree = calculateImportDegree(g, i, 0); // 求入度
nowVex += importDegree;
if (nowVex > maxVex) {
max = i;
maxVex = nowVex;
}
}
printf("度最大的节点下标:%d", max);
}
基于邻接表的深度优先遍历和广度优先遍历及查路径、入度、出度
于 2023-10-12 15:55:27 首次发布