BFS算法篇——打開智慧之門,BFS算法在拓撲排序中的詩意探索(上)

文章目錄

  • 引言
  • 一、拓撲排序的背景
  • 二、BFS算法解決拓撲排序
  • 三、應用場景
  • 四、代碼實現
  • 五、代碼解釋
  • 六、總結

在這里插入圖片描述

引言

在這浩瀚如海的算法世界中,有一扇門,開啟后通向了有序的領域。它便是拓撲排序,這個問題的解決方法猶如一場深刻的哲學思考:在一個由節點和邊構成的有向圖中,如何安排節點的順序,以滿足每一條邊的方向約束?這是一個在計算機科學中至關重要的問題,廣泛應用于任務調度、依賴關系分析等領域。

在求解拓撲排序的問題時,廣度優先搜索(BFS)算法帶著它那獨特的力量,悄然走入我們的視野。BFS不僅僅是圖的遍歷工具,它還能幫助我們揭開拓撲排序的神秘面紗。

在這篇報告中,我們將探討如何用BFS算法實現拓撲排序,揭示其中的算法思想與實現步驟,同時通過C語言代碼實現這一過程。

一、拓撲排序的背景

在計算機科學中,拓撲排序是針對有向無環圖(DAG, Directed Acyclic Graph)的一種排序方法。拓撲排序要求圖中的每一條有向邊 (u, v) 都滿足節點 u 在排序中出現在節點 v 之前。

拓撲排序的問題在于,它要求我們找出一個節點的順序,以確保每個節點的依賴關系被正確處理。該問題廣泛應用于任務調度、課程安排、項目管理等場景中。

二、BFS算法解決拓撲排序

BFS算法通常與圖的層次遍歷相關聯,而在拓撲排序問題中,BFS能夠通過一種特殊的方式——Kahn算法來解決.Kahn算法是一種基于BFS的拓撲排序算法,核心思想如下:

  • 初始化:找出所有入度為0的節點。入度為0意味著這些節點沒有依賴項,可以作為排序的起始節點。
  • 遍歷:將所有入度為0的節點加入隊列,每次從隊列中取出一個節點,輸出該節點,并減少它指向的所有節點的入度。
  • 更新:當某個節點的入度減為0時,將該節點加入隊列。重復此過程,直到所有節點被處理。

BFS的隊列操作確保了我們始終從最早可以處理的節點開始,逐步構建出正確的拓撲順序。

三、應用場景

拓撲排序在多個領域中都有重要應用,尤其是當任務之間有依賴關系時,拓撲排序能夠幫助我們安排任務的執行順序。例如:

  • 任務調度:在多任務系統中,如何按順序執行任務,以確保每個任務的前置任務已完成。
  • 課程安排:在大學課程安排中,如何安排課程的先后順序,確保前置課程在后續課程之前完成。
  • 項目管理:在項目中,如何安排不同子任務的順序,以便最終順利完成項目。

四、代碼實現

下面是一個使用C語言實現BFS算法求解拓撲排序的代碼示例:

#include <stdio.h>
#include <stdlib.h>#define MAX 100// 隊列結構體定義
typedef struct {int items[MAX];int front, rear;
} Queue;// 隊列初始化
void initQueue(Queue* q) {q->front = q->rear = 0;
}// 入隊操作
void enqueue(Queue* q, int item) {q->items[q->rear++] = item;
}// 出隊操作
int dequeue(Queue* q) {return q->items[q->front++];
}// 判斷隊列是否為空
int isEmpty(Queue* q) {return q->front == q->rear;
}// 拓撲排序的BFS實現
void topologicalSortBFS(int graph[MAX][MAX], int n) {int inDegree[MAX] = {0};  // 存儲每個節點的入度Queue q;initQueue(&q);// 計算所有節點的入度for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {if (graph[i][j] == 1) {inDegree[j]++;}}}// 將所有入度為0的節點入隊for (int i = 0; i < n; i++) {if (inDegree[i] == 0) {enqueue(&q, i);}}int count = 0;  // 記錄已輸出的節點數while (!isEmpty(&q)) {int current = dequeue(&q);printf("%d ", current);  // 輸出節點// 遍歷當前節點的鄰接節點,減少它們的入度for (int i = 0; i < n; i++) {if (graph[current][i] == 1) {inDegree[i]--;// 如果入度變為0,將其入隊if (inDegree[i] == 0) {enqueue(&q, i);}}}count++;}// 如果輸出的節點數與圖中的節點數不同,說明圖中存在環,無法進行拓撲排序if (count != n) {printf("\n圖中存在環,無法進行拓撲排序。\n");} else {printf("\n拓撲排序完成。\n");}
}int main() {int graph[MAX][MAX] = {{0, 1, 0, 0, 0},{0, 0, 1, 0, 0},{0, 0, 0, 1, 0},{0, 0, 0, 0, 1},{0, 0, 0, 0, 0}};int n = 5;  // 節點數printf("拓撲排序結果:\n");topologicalSortBFS(graph, n);return 0;
}

五、代碼解釋

  • 圖的表示:我們使用一個二維數組 graph[MAX][MAX] 來表示圖的鄰接矩陣,其中 graph[i][j] 為 1 表示存在從節點 i 到節點 j 的有向邊,0 表示沒有邊。

  • 入度數組:inDegree[MAX] 用來存儲每個節點的入度,表示指向該節點的邊的數量。

  • 隊列操作:我們用隊列來實現BFS,確保節點按照拓撲順序逐一處理。通過 enqueue 和 dequeue 操作,我們可以依次訪問入度為 0 的節點,并逐步更新其他節點的入度。

  • 拓撲排序過程:首先計算每個節點的入度,并將所有入度為 0 的節點入隊。然后,通過逐一訪問隊列中的節點,輸出節點并更新它的鄰接節點的入度。如果某個鄰接節點的入度減為 0,就將該節點加入隊列。

  • 環檢測:如果在處理過程中,我們沒有輸出所有節點,那么圖中必然存在環,無法完成拓撲排序。

六、總結

BFS在拓撲排序中的應用如同一位心思縝密的指揮家,按照特定的規則,逐步安排每一個節點的順序。在這個過程中,算法不僅順利完成了節點的排列,也避免了其中可能出現的循環依賴,確保了排序的正確性。

拓撲排序讓我們看到了一個有序的世界,而BFS算法如同那把鑰匙,為我們打開了通向有序圖形的智慧之門。通過這扇門,我們能夠在復雜的依賴關系中找到秩序,將混亂轉化為優雅,最終走向光明的終點。

本篇關于BFS算法解決拓撲排序的介紹就暫告段落啦,希望能對大家的學習產生幫助,歡迎各位佬前來支持斧正!!!

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/80863.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/80863.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/80863.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Qt開發】信號與槽

目錄 1&#xff0c;信號與槽的介紹 2&#xff0c;信號與槽的運用 3&#xff0c;自定義信號 1&#xff0c;信號與槽的介紹 在Qt框架中&#xff0c;信號與槽機制是一種用于對象間通信的強大工具。它是在Qt中實現事件處理和回調函數的主要方法。 信號&#xff1a;窗口中&#x…

數據庫基礎:概念、原理與實戰示例

在當今信息時代&#xff0c;數據已經成為企業和個人的核心資產。無論是社交媒體、電子商務、金融交易&#xff0c;還是物聯網設備&#xff0c;幾乎所有的現代應用都依賴于高效的數據存儲和管理。數據庫&#xff08;Database&#xff09;作為數據管理的核心技術&#xff0c;幫助…

前端-HTML基本概念

目錄 什么是HTML 常用的瀏覽器引擎是什么&#xff1f; 常見的HTML實體字符 HTML注釋 HTML語義化是什么&#xff1f;為什么要語義化&#xff1f;一定要語義化嗎&#xff1f; 連續空格如何渲染&#xff1f; 聲明文檔類型 哪些字符集編碼支持簡體中文&#xff1f; 如何解…

Linux進程信號處理(26)

文章目錄 前言一、信號的處理時機處理情況“合適”的時機 二、用戶態與內核態概念重談進程地址空間信號的處理過程 三、信號的捕捉內核如何實現信號的捕捉&#xff1f;sigaction 四、信號部分小結五、可重入函數六、volatile七、SIGCHLD 信號總結 前言 這篇就是我們關于信號的最…

C++ 字符格式化輸出

文章目錄 一、簡介二、實現代碼三、實現效果 一、簡介 這里使用std標準庫簡單實現一個字符格式化輸出&#xff0c;方便后續的使用&#xff0c;它有點類似Qt中的QString操作。 二、實現代碼 FMTString.hpp #pragma once#include <cmath> #include <cstdio> #include…

python高級特性

json.dumps({a:1,n:2}) #Python 字典類型轉換為 JSON 對象。相當于jsonify data2 json.loads(json_str)#將 JSON 對象轉換為 Python 字典 異步編程&#xff1a;在異步編程中&#xff0c;程序可以啟動一個長時間運行的任務&#xff0c;然后繼續執行其他任務&#xff0c;而無需等…

ubuntu24離線安裝docker

一、確認ubuntu版本 root@dockerserver:/etc/pam.d# lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 24.04.2 LTS Release: 24.04 Codename: noble 根據codename確認。 docker官方網址下載 https://download.docker.com/linux/…

索尼(sony)攝像機格式化后mp4的恢復方法

索尼(sony)的Alpha 7 Ⅳ系列絕對稱的上是索尼的“全畫幅標桿機型”&#xff0c;A7M4配備了3300萬像素的CMOS&#xff0c;以及全新研發的全畫幅背照式Exmor R?CMOS影像傳感器&#xff0c;搭載BIONZ XR?影像處理器&#xff0c;與旗艦微單?Alpha 1如出一轍。下面我們來看看A7M4…

2025最新出版 Microsoft Project由入門到精通(七)

目錄 優化資源——在資源使用狀況視圖中查看資源的負荷情況 在資源圖表中查看資源的負荷情況 優化資源——資源出現沖突時的原因及處理辦法 資源過度分類的處理解決辦法 首先檢查任務工時的合理性并調整 增加資源供給 回到資源工作表中雙擊對應的過度分配資源 替換資…

最短路與拓撲(1)

1、找最長良序字符串 #include<bits/stdc.h> using namespace std; const int N105; int dis[N]; int vis[N]; int edge[N][N]; int n,m; int vnum;void dij(int u, int v) {// 初始化距離數組和訪問標記for(int i0; i<vnum; i) {vis[i] 0;dis[i] edge[u][i];}// D…

降低60.6%碰撞率!復旦大學地平線CorDriver:首次引入「走廊」增強端到端自動駕駛安全性

導讀 復旦大學&地平線新作-CorDriver: 首次通過引入"走廊"作為中間表征&#xff0c;揭開一個新的范式。預測的走廊作為約束條件整合到軌跡優化過程中。通過擴展優化的可微分性&#xff0c;使優化后的軌跡能無縫地在端到端學習框架中訓練&#xff0c;從而提高安全…

CSS flex:1

在 CSS 中&#xff0c;flex: 1 是一個用于彈性布局&#xff08;Flexbox&#xff09;的簡寫屬性&#xff0c;主要用于控制 flex 項目&#xff08;子元素&#xff09;如何分配父容器的剩余空間。以下是其核心作用和用法&#xff1a; 核心作用 等分剩余空間&#xff1a;讓 flex …

1.6 關于static和final的修飾符

一.static static是靜態修飾符&#xff0c;用于修飾類成員&#xff08;變量&#xff0c;方法&#xff0c;代碼塊&#xff09; 被修飾的類成員屬于類&#xff0c;不必生成示例&#xff0c;即可直接調用屬性或者方法。 關于代碼塊&#xff0c;被static修飾的代碼塊是靜態代碼塊…

數據結構—(鏈表,棧,隊列,樹)

本文章寫的比較亂&#xff0c;屬于是縫合怪&#xff0c;很多細節沒處理&#xff0c;顯得粗糙&#xff0c;日后完善&#xff0c;今天趕時間了。 1. 紅黑樹的修復篇章 2. 紅黑樹的代碼理解&#xff08;部分寫道注釋之中了&#xff09; 3. 隊列與棧的代碼 4. 重要是理解物理邏輯&a…

每日Prompt:發光線條解剖圖

提示詞 一幅數字插畫&#xff0c;描繪了一個 [SUBJECT]&#xff0c;其結構由一組發光、干凈且純凈的藍色線條勾勒而成。畫面設定在深色背景之上&#xff0c;以突出 [SUBJECT] 的形態與特征。某個特定部位&#xff0c;如 [PART]&#xff0c;通過紅色光暈加以強調&#xff0c;以…

【時時三省】(C語言基礎)使用字符串處理函數

山不在高&#xff0c;有仙則名。水不在深&#xff0c;有龍則靈。 ----CSDN 時時三省 在C函數庫中提供了一些用來專門處理字符串的函數&#xff0c;使用方便。幾乎所有版本的C語言編譯系統都提供這些函數。下面介紹幾種常用的函數。 ①puts函數 輸出字符串的函數 其一般形式…

構建可信數據空間需要突破技術、規則和生態三大關鍵

構建可信數據空間需要突破技術、規則和生態三大關鍵&#xff1a;技術上要解決"可用不可見"的隱私計算難題&#xff0c;規則上要建立動態確權和跨境流動的治理框架&#xff0c;生態上要形成多方協同的標準體系。他強調&#xff0c;只有實現技術可控、規則可信、生態協…

模板的使用

模板 模板的概念&#xff1a;模板就是建立一個通用的模具&#xff0c;大大提高復用性 c中模板機制分為兩類 函數模板 建立一個通用函數&#xff0c;其函數返回值類型和形參類型可以不具體定制&#xff0c;用一個虛擬的類型來代表 template<typename T> //template 聲…

YOLOv1:開啟實時目標檢測的新篇章

YOLOv1&#xff1a;開啟實時目標檢測的新篇章 在深度學習目標檢測領域&#xff0c;YOLO&#xff08;You Only Look Once&#xff09;系列算法無疑占據著重要地位。其中&#xff0c;YOLOv1作為開山之作&#xff0c;以其獨特的設計理念和高效的檢測速度&#xff0c;為后續的目標…

vim中的查找

在 Vim 中&#xff0c;使用 n 鍵可以按正向&#xff08;向下&#xff09;繼續查找下一個匹配項。若要反向&#xff08;向上&#xff09;查找&#xff0c;可以使用以下方法&#xff1a; 1. 使用 N 鍵反向查找 在查找命令&#xff08;如 /keyword&#xff09;后&#xff0c;按下…