图的初识·遍历
创始人
2024-03-14 14:07:39
0

文章目录

  • 深度优先搜索[DFS]
    • 实现代码
  • 广度优先搜索【BFS】
    • 思路图解
    • 代码实现·广度优先遍历【BFS】
      • 图的结构

深度优先搜索[DFS]

  • 并不唯一,只是一种情况A−>IA->IA−>I
    在这里插入图片描述

实现代码

在这里插入图片描述

  • 使用邻接表表示图。遍历的时间复杂度O(V+E)O(V+E)O(V+E);邻接矩阵的时间复杂度为O(V2)O(V^2)O(V2)
#include 
#include 
#define MaxVertex 5
typedef char E;
//结点和头节点分开定义,普通结点记录邻接顶点信息
typedef struct node {int nextVertex;struct node *next;
} *Node;
//头节点记录元素
struct HeadNode {E element;struct node * next;
};typedef struct AdjacencyGraph {int vertexCount;//顶点数int edgeCount;//边数struct HeadNode vertex[MaxVertex];
}* Graph;
//初始化
Graph create();
//添加顶点
void addVertex(Graph graph,E element);
//添加边的关系
void addEdge(Graph graph,int a,int b);
//打印邻接表
void printGraph(Graph graph);
//深度优先搜索算法
int dfs(Graph graph,int startVertex,int targetVertex,int* visited);
#include "Map2.h"
//创建
Graph create() {Graph graph=(Graph) malloc(sizeof(struct AdjacencyGraph));graph->vertexCount=graph->edgeCount=0;return graph;
};
//添加顶点
void addVertex(Graph graph,E element) {if(graph->vertexCount>=MaxVertex) return;//添加新节点graph->vertex[graph->vertexCount].element=element;graph->vertex[graph->vertexCount].next=NULL;graph->vertexCount++;//顶点数更新
}
void addEdge(Graph graph,int a,int b) {//定义一个指向链表的头结点的下一结点指向Node node=graph->vertex[a].next;//开辟顶点空间Node newNode=(Node) malloc(sizeof(struct node));newNode->next=NULL;newNode->nextVertex=b;//如果头结点下面没有东西,就直接连接;否则,就遍历到最后一个结点后,添加新节点if(!node) {graph->vertex[a].next=newNode;//注意这里不能使用node,因为我们要真实地改变头节点的next指向}else {do{//如果已经连接到对应的结点,直接返回if(node->nextVertex==b) {free(newNode);newNode=NULL;return ;}//否则一直遍历到最后一个结点if(node->next) node=node->next;else break;//如果遭到了最后一个结点,直接结束}while(true);node->next=newNode;}graph->edgeCount++;//边数计数+1
}
//打印
void printGraph(Graph graph) {for(int i=0;ivertexCount;i++) {printf("%d | %c",i,graph->vertex[i].element);Node node=graph->vertex[i].next;while(node) {printf("-> %d",node->nextVertex);node=node->next;}printf("\n");}
}
/*** 深度优先搜索算法* @param graph 图* @param startVertex 起点顶点下标* @param targetVertex 目标顶点下标* @param visited 已到达过的顶点数组*/
int dfs(Graph graph,int startVertex,int targetVertex,int* visited) {visited[startVertex]=1;//标记访问过的结点//大一当前结点printf("%c->",graph->vertex[startVertex].element);//如果当前顶点就是要找的顶点,就直接返回if(startVertex==targetVertex) return 1;//遍历当前顶点所有的分支Node node=graph->vertex[startVertex].next;while(node) {//如果已经到过[做的其他分支、回头路],就停止if(!visited[node->nextVertex]) {//没到过就继续往下走//如果查找成功就返回一,不用再看其他分支。if(dfs(graph,node->nextVertex,targetVertex,visited)) {return 1;}}node=node->next;}return 0;//当下的遍历都结束后,还是没有找到就返回零
}
#include "Map2.h"int main() {Graph graph1 = create();for (int c = 'A'; c <= 'F'; c++) {addVertex(graph1, (char) c);}addEdge(graph1, 0, 1);//A->BaddEdge(graph1, 1, 2);//B->CaddEdge(graph1, 1, 3);//B->DaddEdge(graph1, 1, 4);//D->E//addEdge(graph1, 4, 5);//E->FprintGraph(graph1);int arr[graph1->vertexCount];for(int i=0;ivertexCount;i++) {arr[i]=0;}printf("\n%d",dfs(graph1,0,5,arr));return 0;
}

在这里插入图片描述

广度优先搜索【BFS】

  • 先探索顶点的所有分支,然后再去看这些分支的所有分支。
  • 实质上是更尽可能地探索更广的范围。

思路图解

从A结点开始探索,A入队列。队列状态:A然后,再将其下一个结点B入队,A出队。队列状态:B从A结点开始探索,A入队列。\\ 队列状态:A\\ 然后,再将其下一个结点B入队,A出队。\\ 队列状态:B\\ 从A结点开始探索,A入队列。队列状态:A然后,再将其下一个结点B入队,A出队。队列状态:B
在这里插入图片描述
将B的下一级结点入队队列状态:B−>H−>G−>K将B出队队列状态:H−>G−>K将B的下一级结点入队\\ 队列状态:B->H->G->K\\ 将B出队\\ 队列状态:H->G->K 将B的下一级结点入队队列状态:B−>H−>G−>K将B出队队列状态:H−>G−>K
在这里插入图片描述
依次按照队头到队尾的顺序,将其子节点入队,本结点出队。C入队队列状态:H−>G−>K−>CH出队对列状态:G−>K−>C依次按照队头到队尾的顺序,将其子节点入队,本结点出队。\\ C入队\\ 队列状态:H->G->K->C\\ H出队\\ 对列状态:G->K->C 依次按照队头到队尾的顺序,将其子节点入队,本结点出队。C入队队列状态:H−>G−>K−>CH出队对列状态:G−>K−>C
在这里插入图片描述
D、F入队;C已入队,所以无需再次入队。队列状态:G−>K−>C−>D−>FG出队对列状态:K−>C−>D−>FD、F入队;C已入队,所以无需再次入队。\\ 队列状态:G->K->C->D->F\\ G出队\\ 对列状态:K->C->D->F\\ D、F入队;C已入队,所以无需再次入队。队列状态:G−>K−>C−>D−>FG出队对列状态:K−>C−>D−>F
在这里插入图片描述
K没有下一个结点,所以直接将K出队。队列状态:C−>D−>FK没有下一个结点,所以直接将K出队。\\ 队列状态:C->D->F K没有下一个结点,所以直接将K出队。队列状态:C−>D−>F
在这里插入图片描述
再依次遍历队头的下一个结点E入队队列状态:C−>D−>F−>EC出队队列状态:D−>F−>E再依次遍历队头的下一个结点\\ E入队\\ 队列状态:C->D->F->E C出队\\ 队列状态:D->F->E 再依次遍历队头的下一个结点E入队队列状态:C−>D−>F−>EC出队队列状态:D−>F−>E
在这里插入图片描述
因为D、F没有下一级邻接点,所以将D、F出队即可队列状态:E因为D、F没有下一级邻接点,所以将D、F出队即可\\ 队列状态:E 因为D、F没有下一级邻接点,所以将D、F出队即可队列状态:E

在这里插入图片描述
I、J入队队列状态:E−>I−>JE出队队列状态:I−>JI、J入队\\ 队列状态:E->I->J E出队\\ 队列状态:I->J I、J入队队列状态:E−>I−>JE出队队列状态:I−>J
在这里插入图片描述
最后再将队列的内容全部出队队列状态:空结束搜索最后再将队列的内容全部出队\\ 队列状态:空\\ 结束搜索 最后再将队列的内容全部出队队列状态:空结束搜索

代码实现·广度优先遍历【BFS】

  • 存储结构:邻接表

图的结构

在这里插入图片描述

typedef int T;
struct QueueNode{T element;struct QueueNode * next;
};
typedef struct QueueNode* QNode;
struct Queue{QNode front,rear;
};
typedef struct Queue* LinkedQueue;
int initQueue(LinkedQueue queue) {QNode node=(QNode) malloc(sizeof(struct QueueNode));if(node==NULL) return 0;queue->front=queue->rear=node;return 1;
}int offerQueue(LinkedQueue queue,T element) {QNode node=(QNode) malloc(sizeof(struct QueueNode));if(node== NULL) return 0;node->element=element;queue->rear->next=node;queue->rear=node;return 1;
}
int isEmpty(LinkedQueue queue){return queue->front==queue->rear;
};
T pollQueue(LinkedQueue queue) {T e=queue->front->next->element;QNode node=queue->front->next;queue->front->next=queue->front->next->next;if(queue->rear==node) queue->rear=queue->front;free(node);return e;
}
  • BFS
/**** @param graph 图* @param startVertex 起点顶点下标* @param targetVertex 目标顶点下标* @param visited 已到达过的顶点数组* @param queue 辅助作用的队列* @return*/
int bfs(Graph graph,int startVertex,int targetVertex,int* visited,LinkedQueue queue) {offerQueue(queue,startVertex);//头节点入队visited[startVertex]=1;//立马已标记//当队列不为空时,进行操作while(!isEmpty(queue)) {int next= pollQueue(queue);//从队列中取出一个顶点打印printf("%c->",graph->vertex[next].element);Node node=graph->vertex[next].next;//下一个结点//当当前结点的下一个结点存在时,进行入队操作while(node) {//如果找到目标结点,返回trueif(node->nextVertex==targetVertex) return true;if(!visited[node->nextVertex]) {//!0==1未访问offerQueue(queue,node->nextVertex);//入队列visited[node->nextVertex]=1;//访问标记}node=node->next;//进行下一个结点}}return false;
}
  • Main.cpp
Graph graph1 = create();
for (int c = 'A'; c <= 'F'; c++) {addVertex(graph1, (char) c);
}
addEdge(graph1, 0, 1);//A->B
addEdge(graph1, 1, 2);//B->C
addEdge(graph1, 1, 3);//B->D
addEdge(graph1, 1, 4);//D->E
addEdge(graph1, 4, 5);//E->F
printGraph(graph1);
int arr1[graph1->vertexCount];
for(int i=0;ivertexCount;i++) {arr1[i]=0;
}
struct Queue queue;
initQueue(&queue);
bfs(graph1,0,5,arr1,&queue);

在这里插入图片描述

相关内容

热门资讯

准确适用法律,有效震慑“职业闭... 据媒体报道,上海市公安局经侦总队近日牵头侦破一起新型“职业闭店人”合同诈骗案,抓获顾某、韩某等4名犯...
男子分居期间贷款32.5万元买... 12月24日,记者从新疆法治报获悉:近日塔城地区中级人民法院审结了一起案件,明确表明车贷因未用于共同...
盛路通信(002446)披露与... 截至2025年12月25日收盘,盛路通信(002446)报收于10.75元,较前一交易日上涨10.0...
德州新华书店组织专题研讨 深入... 大众网记者 张冉 通讯员 李晓腾 德州报道 近日,德州新华书店组织召开全民阅读相关政策专题研讨交流会...
阿尔及利亚立法认定“法国殖民是... 阿尔及利亚国民议会(众议院)24日晚表决通过法案,将法国对这个非洲国家曾经的殖民统治定性为“犯罪”,...
专访鲁政委:结构性货币政策工具... 2025年,站在“十四五”收官与“十五五”规划谋篇的历史衔接点上,中国经济在多重变局中展现出韧性,金...
广末凉子有望明年复出!曾飙速1... 搜狐娱乐讯 据日媒,广末凉子有望明年正式复出,相关人士称她一直很规矩,会向各界发邮件汇报近况,“这次...
浙江东日(600113)发布投... 截至2025年12月25日收盘,浙江东日(600113)报收于67.29元,较前一交易日上涨4.34...
广电网络:近12个月累计诉讼及... 中证智能财讯 广电网络(600831)12月25日晚间发布累计诉讼、仲裁情况公告,近十二个月内,公司...
封关后第一批!198公斤椰子油... 12月23日,海南保亭黎族苗族自治县一家食品企业生产的198公斤初榨椰子油,通过海口新海港和南港“二...