【數(shù)據(jù)結(jié)構(gòu)】廣度優(yōu)先搜索算法BFS

對(duì)于廣度優(yōu)先遍歷算法DFS可以參考前一篇文章【數(shù)據(jù)結(jié)構(gòu)】深度優(yōu)先搜索算法DFS

廣度優(yōu)先遍歷

廣度優(yōu)先遍歷(Breadth_First_Search),又稱為廣度優(yōu)先搜索,簡(jiǎn)稱BFS棒掠。

圖的BFS類似于樹的層序遍歷烟很。

廣度優(yōu)先遍歷
  • 如圖將左邊的圖變形,得到右邊的圖芹橡,然后一層一層的遍歷林说。
  • 這里借助一個(gè)隊(duì)列來實(shí)現(xiàn)一層一層的遍歷。

鄰接矩陣的BFS

核心代碼

/**
 * 鄰接矩陣的廣度優(yōu)先遍歷算法
 */
void BFSTraverse(MGraph G){
    
    int i,j;
    Queue Q;
    
    for (i = 0; i < G.numVertexes; i++) {
        visited[i] = FALSE;
    }
    
    InitQueue(&Q);  // 初始化輔助隊(duì)列
    
    for (i = 0; i < G.numVertexes; i++) {  // 對(duì)每個(gè)頂點(diǎn)做循環(huán)
        
        if (!visited[i]) {
            
            visited[i] = TRUE;
            printf("%c", G.vexs[i]);
            EnQueue(&Q, i);  // 頂點(diǎn)入隊(duì)列
            
            while (!QueueEmpty(Q)) {  // 隊(duì)列不為空
                DeQueue(&Q, &i);  // 將隊(duì)列元素出隊(duì)列
                
                for (j = 0; j < G.numVertexes; j++) {
                    if (G.arc[i][j] == 1 && !visited[j]) {  // 判斷其他頂點(diǎn)若與當(dāng)前頂點(diǎn)存在邊且未訪問過
                        visited[j] = TRUE;
                        printf("%c", G.vexs[j]);
                        EnQueue(&Q, j);
                    }
                }
            }
        }
    }
}

附上隊(duì)列操作的代碼

#pragma 用到的隊(duì)列
//循環(huán)隊(duì)列的存儲(chǔ)結(jié)構(gòu)
typedef struct {
    int data[MAXSIZE];
    int front;  // 頭指針
    int rear;   // 尾指針屯伞,若隊(duì)列不為空,指向隊(duì)列尾元素的下一個(gè)位置
}Queue;

/**
 * 初始化一個(gè)空隊(duì)列
 */
Status InitQueue(Queue *Q){
    Q->front = 0;
    Q->rear = 0;
    return OK;
}

/**
 * 判斷隊(duì)列是否為空
 */
Status QueueEmpty(Queue Q){
    if (Q.front == Q.rear)
        return TRUE;
    else
        return FALSE;
}

/**
 * 插入
 */
Status EnQueue(Queue * Q, int e){
    if ((Q->rear + 1) % MAXSIZE == Q->front)  // 隊(duì)列滿
        return ERROR;
    
    Q->data[Q->rear] = e;             // 元素e賦值給對(duì)尾
    Q->rear = (Q->rear + 1)% MAXSIZE;  // rear指針后移一個(gè)位置
    
    return OK;
}

/**
 * 刪除隊(duì)列中的元素
 */
Status DeQueue(Queue * Q, int *e){
    
    if (Q->front == Q->rear)
        return ERROR;
    *e = Q->data[Q->front];  // 將隊(duì)頭元素賦值給e
    Q->front = (Q->front+1)%MAXSIZE;  // front指針后移
    
    return OK;
}

鄰接表的BFS

核心代碼

void BFSTraverse(GraphAdjList GL){
    
    int i;
    EdgeNode *p;
    
    Queue Q;
    
    for (i = 0; i < GL->numVertexes; i++)
        visited[i] = FALSE;
    
    InitQueue(&Q);
    
    for (i = 0; i < GL->numVertexes; i++) {
        
        if (!visited[i]) {
            
            visited[i] = TRUE;
            printf("%c", GL->adjList[i].data);  // 打印頂點(diǎn)
            
            EnQueue(&Q, i);
            
            while (!QueueEmpty(Q)) {
                
                DeQueue(&Q, &i);
                
                p = GL->adjList[i].firstedge;  // 找到當(dāng)前頂點(diǎn)的邊表鏈表頭指針
                
                while (p) {
                    if (!visited[p->adjvex]) {  // 若次頂點(diǎn)沒有被訪問過
                        
                        visited[p->adjvex] = TRUE;
                        printf("%c", GL->adjList[p->adjvex].data);
                        EnQueue(&Q, p->adjvex);   // 將次頂點(diǎn)入隊(duì)列
                        
                    }
                    p = p->next;
                }
            }
        }
    }
}

圖的DFS與BFS

  • 圖的深度優(yōu)先搜索算法和廣度優(yōu)先搜索算法在時(shí)間復(fù)雜度上是一樣的劣摇。
  • 深度優(yōu)先更適合目標(biāo)比較明確度秘,以找到目標(biāo)為目的的情況。
  • 廣度優(yōu)先更適合在不斷擴(kuò)大遍歷范圍時(shí)找到相對(duì)最優(yōu)解的情況饵撑。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末剑梳,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子滑潘,更是在濱河造成了極大的恐慌垢乙,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件语卤,死亡現(xiàn)場(chǎng)離奇詭異追逮,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)粹舵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門钮孵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人眼滤,你說我怎么就攤上這事巴席。” “怎么了诅需?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵漾唉,是天一觀的道長(zhǎng)荧库。 經(jīng)常有香客問我,道長(zhǎng)赵刑,這世上最難降的妖魔是什么分衫? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮般此,結(jié)果婚禮上蚪战,老公的妹妹穿的比我還像新娘。我一直安慰自己铐懊,他們只是感情好屎勘,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著居扒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪丑慎。 梳的紋絲不亂的頭發(fā)上喜喂,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音竿裂,去河邊找鬼玉吁。 笑死,一個(gè)胖子當(dāng)著我的面吹牛腻异,可吹牛的內(nèi)容都是我干的进副。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼悔常,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼影斑!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起机打,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤矫户,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后残邀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體皆辽,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年芥挣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了驱闷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡空免,死狀恐怖空另,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蹋砚,我是刑警寧澤痹换,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布征字,位于F島的核電站,受9級(jí)特大地震影響娇豫,放射性物質(zhì)發(fā)生泄漏匙姜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一冯痢、第九天 我趴在偏房一處隱蔽的房頂上張望氮昧。 院中可真熱鬧,春花似錦浦楣、人聲如沸袖肥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽椎组。三九已至,卻和暖如春历恐,著一層夾襖步出監(jiān)牢的瞬間寸癌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國打工弱贼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蒸苇,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓吮旅,卻偏偏與公主長(zhǎng)得像溪烤,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子庇勃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容