- 数据结构与算法
- DSA - 首页
- DSA - 概述
- DSA - 环境设置
- DSA - 算法基础
- DSA - 渐近分析
- 数据结构
- DSA - 数据结构基础
- DSA - 数据结构和类型
- DSA - 数组数据结构
- 链表
- DSA - 链表数据结构
- DSA - 双向链表数据结构
- DSA - 循环链表数据结构
- 栈与队列
- DSA - 栈数据结构
- DSA - 表达式解析
- DSA - 队列数据结构
- 搜索算法
- DSA - 搜索算法
- DSA - 线性搜索算法
- DSA - 二分搜索算法
- DSA - 插值搜索
- DSA - 跳跃搜索算法
- DSA - 指数搜索
- DSA - 斐波那契搜索
- DSA - 子列表搜索
- DSA - 散列表
- 排序算法
- DSA - 排序算法
- DSA - 冒泡排序算法
- DSA - 插入排序算法
- DSA - 选择排序算法
- DSA - 归并排序算法
- DSA - 希尔排序算法
- DSA - 堆排序
- DSA - 桶排序算法
- DSA - 计数排序算法
- DSA - 基数排序算法
- DSA - 快速排序算法
- 图数据结构
- DSA - 图数据结构
- DSA - 深度优先遍历
- DSA - 广度优先遍历
- DSA - 生成树
- 树数据结构
- DSA - 树数据结构
- DSA - 树的遍历
- DSA - 二叉搜索树
- DSA - AVL树
- DSA - 红黑树
- DSA - B树
- DSA - B+树
- DSA - 伸展树
- DSA - 字典树 (Trie)
- DSA - 堆数据结构
- 递归
- DSA - 递归算法
- DSA - 使用递归的汉诺塔
- DSA - 使用递归的斐波那契数列
- 分治法
- DSA - 分治法
- DSA - 最大最小问题
- DSA - Strassen矩阵乘法
- DSA - Karatsuba算法
- 贪心算法
- DSA - 贪心算法
- DSA - 旅行商问题(贪心法)
- DSA - Prim最小生成树
- DSA - Kruskal最小生成树
- DSA - Dijkstra最短路径算法
- DSA - 地图着色算法
- DSA - 分数背包问题
- DSA - 带截止期限的作业排序
- DSA - 最优合并模式算法
- 动态规划
- DSA - 动态规划
- DSA - 矩阵链乘法
- DSA - Floyd-Warshall算法
- DSA - 0-1背包问题
- DSA - 最长公共子序列算法
- DSA - 旅行商问题(动态规划法)
- 近似算法
- DSA - 近似算法
- DSA - 顶点覆盖算法
- DSA - 集合覆盖问题
- DSA - 旅行商问题(近似算法)
- 随机化算法
- DSA - 随机化算法
- DSA - 随机化快速排序算法
- DSA - Karger最小割算法
- DSA - Fisher-Yates洗牌算法
- DSA有用资源
- DSA - 问答
- DSA - 快速指南
- DSA - 有用资源
- DSA - 讨论
广度优先搜索 (BFS) 算法
广度优先搜索 (BFS) 算法
广度优先搜索 (BFS) 算法以广度优先的方式遍历图数据结构,以搜索满足一组条件的节点。它使用队列来记住下次搜索的起始顶点,当任何迭代中出现死锁时。
广度优先搜索 (BFS) 算法从树根开始,在移动到下一深度级别的节点之前,探索当前深度级别上的所有节点。
如上例所示,BFS算法首先从A到B到E到F遍历,然后到C和G,最后到D。它采用以下规则。
规则1 - 访问相邻的未访问顶点。将其标记为已访问。显示它。将其插入队列。
规则2 - 如果找不到相邻顶点,则从队列中移除第一个顶点。
规则3 - 重复规则1和规则2,直到队列为空。
步骤 | 遍历 | 描述 |
---|---|---|
1 | 初始化队列。 | |
2 | 我们从访问S(起始节点)开始,并将其标记为已访问。 | |
3 | 然后我们看到S的未访问相邻节点。在这个例子中,我们有三个节点,但按字母顺序我们选择A,将其标记为已访问并将其入队。 | |
4 | 接下来,S的未访问相邻节点是B。我们将其标记为已访问并将其入队。 | |
5 | 接下来,S的未访问相邻节点是C。我们将其标记为已访问并将其入队。 | |
6 | 现在,S没有未访问的相邻节点了。因此,我们出队并找到A。 | |
7 | 从A我们有D作为未访问的相邻节点。我们将其标记为已访问并将其入队。 |
在这个阶段,我们没有未标记(未访问)的节点了。但是根据算法,我们继续出队以获得所有未访问的节点。当队列为空时,程序结束。
示例
以下是各种编程语言中广度优先搜索 (BFS) 算法的实现:
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #define MAX 5 struct Vertex { char label; bool visited; }; //queue variables int queue[MAX]; int rear = -1; int front = 0; int queueItemCount = 0; //graph variables //array of vertices struct Vertex* lstVertices[MAX]; //adjacency matrix int adjMatrix[MAX][MAX]; //vertex count int vertexCount = 0; //queue functions void insert(int data) { queue[++rear] = data; queueItemCount++; } int removeData() { queueItemCount--; return queue[front++]; } bool isQueueEmpty() { return queueItemCount == 0; } //graph functions //add vertex to the vertex list void addVertex(char label) { struct Vertex* vertex = (struct Vertex*) malloc(sizeof(struct Vertex)); vertex->label = label; vertex->visited = false; lstVertices[vertexCount++] = vertex; } //add edge to edge array void addEdge(int start,int end) { adjMatrix[start][end] = 1; adjMatrix[end][start] = 1; } //display the vertex void displayVertex(int vertexIndex) { printf("%c ",lstVertices[vertexIndex]->label); } //get the adjacent unvisited vertex int getAdjUnvisitedVertex(int vertexIndex) { int i; for(i = 0; i<vertexCount; i++) { if(adjMatrix[vertexIndex][i] == 1 && lstVertices[i]->visited == false) return i; } return -1; } void breadthFirstSearch() { int i; //mark first node as visited lstVertices[0]->visited = true; //display the vertex displayVertex(0); //insert vertex index in queue insert(0); int unvisitedVertex; while(!isQueueEmpty()) { //get the unvisited vertex of vertex which is at front of the queue int tempVertex = removeData(); //no adjacent vertex found while((unvisitedVertex = getAdjUnvisitedVertex(tempVertex)) != -1) { lstVertices[unvisitedVertex]->visited = true; displayVertex(unvisitedVertex); insert(unvisitedVertex); } } //queue is empty, search is complete, reset the visited flag for(i = 0;i<vertexCount;i++) { lstVertices[i]->visited = false; } } int main() { int i, j; for(i = 0; i<MAX; i++) { // set adjacency for(j = 0; j<MAX; j++) // matrix to 0 adjMatrix[i][j] = 0; } addVertex('S'); // 0 addVertex('A'); // 1 addVertex('B'); // 2 addVertex('C'); // 3 addVertex('D'); // 4 addEdge(0, 1); // S - A addEdge(0, 2); // S - B addEdge(0, 3); // S - C addEdge(1, 4); // A - D addEdge(2, 4); // B - D addEdge(3, 4); // C - D printf("\nBreadth First Search: "); breadthFirstSearch(); return 0; }
输出
Breadth First Search: S A B C D
//C++ code for Breadth First Traversal #include <iostream> #include <stdlib.h> #include <stdbool.h> #define MAX 5 struct Vertex { char label; bool visited; }; //queue variables int queue[MAX]; int rear = -1; int front = 0; int queueItemCount = 0; //graph variables //array of vertices struct Vertex* lstVertices[MAX]; //adjacency matrix int adjMatrix[MAX][MAX]; //vertex count int vertexCount = 0; //queue functions void insert(int data) { queue[++rear] = data; queueItemCount++; } int removeData() { queueItemCount--; return queue[front++]; } bool isQueueEmpty() { return queueItemCount == 0; } //graph functions //add vertex to the vertex list void addVertex(char label) { struct Vertex* vertex = (struct Vertex*) malloc(sizeof(struct Vertex)); vertex->label = label; vertex->visited = false; lstVertices[vertexCount++] = vertex; } //add edge to edge array void addEdge(int start,int end) { adjMatrix[start][end] = 1; adjMatrix[end][start] = 1; } //display the vertex void displayVertex(int vertexIndex) { std::cout << lstVertices[vertexIndex]->label << " "; } //get the adjacent unvisited vertex int getAdjUnvisitedVertex(int vertexIndex) { int i; for(i = 0; i<vertexCount; i++) { if(adjMatrix[vertexIndex][i] == 1 && lstVertices[i]->visited == false) return i; } return -1; } void breadthFirstSearch() { int i; //mark first node as visited lstVertices[0]->visited = true; //display the vertex displayVertex(0); //insert vertex index in queue insert(0); int unvisitedVertex; while(!isQueueEmpty()) { //get the unvisited vertex of vertex which is at front of the queue int tempVertex = removeData(); //no adjacent vertex found while((unvisitedVertex = getAdjUnvisitedVertex(tempVertex)) != -1) { lstVertices[unvisitedVertex]->visited = true; displayVertex(unvisitedVertex); insert(unvisitedVertex); } } //queue is empty, search is complete, reset the visited flag for(i = 0;i<vertexCount;i++) { lstVertices[i]->visited = false; } } int main() { int i, j; for(i = 0; i<MAX; i++) { // set adjacency for(j = 0; j<MAX; j++) // matrix to 0 adjMatrix[i][j] = 0; } addVertex('S'); // 0 addVertex('A'); // 1 addVertex('B'); // 2 addVertex('C'); // 3 addVertex('D'); // 4 addEdge(0, 1); // S - A addEdge(0, 2); // S - B addEdge(0, 3); // S - C addEdge(1, 4); // A - D addEdge(2, 4); // B - D addEdge(3, 4); // C - D std::cout << "Breadth First Search: "; breadthFirstSearch(); return 0; }
输出
Breadth First Search: S A B C D
//Java code for Breadth First Traversal import java.util.LinkedList; import java.util.Queue; class Vertex { char label; boolean visited; public Vertex(char label) { this.label = label; visited = false; } } public class Graph { private static final int MAX = 5; private Vertex[] lstVertices; private int[][] adjMatrix; private int vertexCount; public Graph() { lstVertices = new Vertex[MAX]; adjMatrix = new int[MAX][MAX]; vertexCount = 0; } private void addVertex(char label) { Vertex vertex = new Vertex(label); lstVertices[vertexCount++] = vertex; } private void addEdge(int start, int end) { adjMatrix[start][end] = 1; adjMatrix[end][start] = 1; } private void displayVertex(int vertexIndex) { System.out.print(lstVertices[vertexIndex].label + " "); } private int getAdjUnvisitedVertex(int vertexIndex) { for (int i = 0; i < vertexCount; i++) { if (adjMatrix[vertexIndex][i] == 1 && !lstVertices[i].visited) return i; } return -1; } private void breadthFirstSearch() { lstVertices[0].visited = true; displayVertex(0); Queue<Integer> queue = new LinkedList<>(); queue.add(0); while (!queue.isEmpty()) { int tempVertex = queue.poll(); int unvisitedVertex; while ((unvisitedVertex = getAdjUnvisitedVertex(tempVertex)) != -1) { lstVertices[unvisitedVertex].visited = true; displayVertex(unvisitedVertex); queue.add(unvisitedVertex); } } // Reset the visited flag for (int i = 0; i < vertexCount; i++) { lstVertices[i].visited = false; } } public static void main(String[] args) { Graph graph = new Graph(); for (int i = 0; i < MAX; i++) { for (int j = 0; j < MAX; j++) graph.adjMatrix[i][j] = 0; } graph.addVertex('S'); // 0 graph.addVertex('A'); // 1 graph.addVertex('B'); // 2 graph.addVertex('C'); // 3 graph.addVertex('D'); // 4 graph.addEdge(0, 1); // S - A graph.addEdge(0, 2); // S - B graph.addEdge(0, 3); // S - C graph.addEdge(1, 4); // A - D graph.addEdge(2, 4); // B - D graph.addEdge(3, 4); // C - D System.out.print("Breadth First Search: "); graph.breadthFirstSearch(); } }
输出
Breadth First Search: S A B C D
#Python program for Breadth First Search # defining MAX 5 MAX = 5 class Vertex: def __init__(self, label): self.label = label self.visited = False # queue variables queue = [0] * MAX rear = -1 front = 0 queueItemCount = 0 # graph variables #array of vertices lstVertices = [None] * MAX #adjacency matrix adjMatrix = [[0] * MAX for _ in range(MAX)] #vertex count vertexCount = 0 # queue functions def insert(data): global rear, queueItemCount rear += 1 queue[rear] = data queueItemCount += 1 def removeData(): global front, queueItemCount queueItemCount -= 1 data = queue[front] front += 1 return data def isQueueEmpty(): return queueItemCount == 0 # graph functions #add vertex to the vertex list def addVertex(label): global vertexCount vertex = Vertex(label) lstVertices[vertexCount] = vertex vertexCount += 1 #add edge to edge array def addEdge(start, end): adjMatrix[start][end] = 1 adjMatrix[end][start] = 1 #Display the vertex def displayVertex(vertexIndex): print(lstVertices[vertexIndex].label, end=" ") #Get the adjacent unvisited vertex def getAdjUnvisitedVertex(vertexIndex): for i in range(vertexCount): if adjMatrix[vertexIndex][i] == 1 and not lstVertices[i].visited: return i return -1 def breadthFirstSearch(): #mark first node as visited lstVertices[0].visited = True #Display the vertex displayVertex(0) #insert vertex index in queue insert(0) while not isQueueEmpty(): #get the unvisited vertex of vertex which is at front of the queue tempVertex = removeData() #no adjacent vertex found unvisitedVertex = getAdjUnvisitedVertex(tempVertex) while unvisitedVertex != -1: lstVertices[unvisitedVertex].visited = True displayVertex(unvisitedVertex) insert(unvisitedVertex) unvisitedVertex = getAdjUnvisitedVertex(tempVertex) #queue is empty, search is complete, reset the visited flag for i in range(vertexCount): lstVertices[i].visited = False # main function if __name__ == "__main__": #set adjacency for i in range(MAX): #matrix to 0 for j in range(MAX): adjMatrix[i][j] = 0 addVertex('S') addVertex('A') addVertex('B') addVertex('C') addVertex('D') addEdge(0, 1) addEdge(0, 2) addEdge(0, 3) addEdge(1, 4) addEdge(2, 4) addEdge(3, 4) print("Breadth First Search: ", end="") breadthFirstSearch()
输出
Breadth First Search: S A B C D
BFS算法的复杂度
时间复杂度
BFS算法的时间复杂度表示为O(V + E),其中V是节点数,E是边数。
空间复杂度
BFS算法的空间复杂度为O(V)。
广告