- 数据结构与算法
- 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 - 尝试
- DSA-堆
- 递归
- DSA - 递归基础知识
- DSA - 河内塔
- DSA - 斐波那契数列
- DSA 有用资源
- DSA - 问题与解答
- DSA - 快速指南
- DSA - 有用的资源
- DSA - 讨论
数据结构-广度优先遍历
广度优先搜索(BFS)算法以广度运动方式遍历图,并使用队列来记住在任何迭代中出现死胡同时获取下一个顶点以开始搜索。
如上面给出的示例,BFS 算法首先从 A 遍历到 B,再到 E,再到 F,然后再遍历到 C,最后遍历到 D。它采用以下规则。
规则 1 - 访问相邻的未访问顶点。将其标记为已访问。显示它。将其插入队列中。
规则 2 - 如果未找到相邻顶点,则从队列中删除第一个顶点。
规则 3 - 重复规则 1 和规则 2,直到队列为空。
步 | 遍历 | 描述 |
---|---|---|
1 | 初始化队列。 | |
2 | 我们从访问S(起始节点)开始,并将其标记为已访问。 | |
3 | 然后我们从S中看到一个未访问的相邻节点。在此示例中,我们有三个节点,但按字母顺序我们选择A,将其标记为已访问并将其排入队列。 | |
4 | 接下来,来自S 的未访问的相邻节点是B。我们将其标记为已访问并将其排入队列。 | |
5 | 接下来,来自S 的未访问的相邻节点是C。我们将其标记为已访问并将其排入队列。 | |
6 | 现在,S就没有未访问过的相邻节点了。因此,我们出队并找到A。 | |
7 | 从A我们有D作为未访问的相邻节点。我们将其标记为已访问并将其排入队列。 |
在此阶段,我们没有未标记(未访问)的节点。但根据算法,我们继续出队以获得所有未访问的节点。当队列清空时,程序结束。
例子
#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