图的深度优先搜索和广度优先搜索

本文介绍如何使用C++实现基于邻接链表的图数据结构,并通过广度优先搜索(BFS)与深度优先搜索(DFS)算法进行图遍历。示例代码展示了如何从矩阵形式的图转换为邻接链表形式,并提供了具体的BFS和DFS实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

图见下:
这里写图片描述
c++代码:对矩阵的操作比较简单,现在将矩阵转化成邻接链表:
这里写图片描述

#include <iostream>
#include <queue>
#include <stack>
using namespace std;

//0:表示不连通 
//1:表示连通 
//无自环路 
const int graph_arr[11][11] = {
    {0,1,0,0,0,0,1,0,0,1,1},//V0
    {1,0,1,0,0,1,1,0,0,0,1},//V1
    {0,1,0,1,1,0,0,0,1,0,0},//V2
    {0,0,1,0,1,0,0,0,0,0,0},//V3
    {0,0,1,1,0,1,0,0,0,0,0},//V4
    {0,1,0,0,1,0,0,0,0,0,0},//V5
    {1,1,0,0,0,0,0,1,0,0,0},//V6
    {0,0,0,0,0,0,1,0,1,1,0},//V7
    {0,0,1,0,0,0,0,1,0,0,0},//V8
    {1,0,0,0,0,0,0,1,0,0,1},//V9
    {1,1,0,0,0,0,0,0,0,1,0} //V10
};

bool visited[11] = {false,false,false,false,false,false,false,false,false,false,false};
//bool visited[11] = {false};

struct Node{
    int no;     //顶点标号 
    struct Node* next;  //与该顶点相连的顶点 
    Node():no(-1),next(NULL){

    }
};

struct EdgeNode{
    struct Node* first_node;//每个便表集合的头节点,也就是 V0,V1,V2...V10 
    struct EdgeNode* next;  //指向下一个头节点 
    int nodes_num;
    EdgeNode():nodes_num(-1),first_node(NULL),next(NULL){

    }
};

/**
*   初始化图的邻接链表 
*/
EdgeNode* init_graph(){
    EdgeNode* graph = (EdgeNode*)malloc(sizeof(struct EdgeNode));
    EdgeNode* _graph = graph; 

    for(int i=0;i<11;i++){
        Node* node = (Node*)malloc(sizeof(struct Node));
        node->no = i;
        graph->first_node = node;
        EdgeNode* tmp0 = (EdgeNode*)malloc(sizeof(struct EdgeNode));
        graph->next = tmp0;
        graph->nodes_num = 0;

        for(int j=0;j<11;j++){
            if(graph_arr[i][j] == 1){
                Node* tmp = (Node*)malloc(sizeof(struct Node));
                tmp->no = j;
                node->next = tmp;
                node = tmp;
                graph->nodes_num ++;
            }
        }
        graph = tmp0;
    }
    return _graph;
} 

/**
*   邻接链表 BFS 
*   非递归方式实现 
*/ 
void BFS(EdgeNode* graph){
    queue<EdgeNode*> que;
    EdgeNode* tmp = graph;
    que.push(tmp);
    while(!que.empty()){
        tmp = que.front();
        que.pop();
        Node* node = tmp->first_node;
        for(int j=0;j<= tmp->nodes_num;j++){
            if(!visited[node->no]){
                cout<<"编号:"<<node->no<<endl;
                visited[node->no] = true;
                EdgeNode* tmp0 = tmp->next;
                while(tmp0->next){
                    if(tmp0->first_node->no == node->no){
                        que.push(tmp0);
                        break;
                    }
                    tmp0 = tmp0->next;
                }
            }
            node = node->next;
        }
    }
}
/**
*   邻接链表 DFS 
*   递归方式实现 
*/ 
void DFS(EdgeNode* graph){
    EdgeNode* tmp = graph;
    Node* node = tmp->first_node;
    for(int j=0;j<= tmp->nodes_num;j++){
        if(!visited[node->no]){
            cout<<"编号:"<<node->no<<endl;
            visited[node->no] = true;
            EdgeNode* tmp0 = tmp->next;
            while(tmp0->next){
                if(tmp0->first_node->no == node->no){
                    DFS(tmp0);
                    break;
                }
                tmp0 = tmp0->next;
            }
        }
        node = node->next;
    }
}

//寻找临接表中某个便表集合中没有被访问的结点 
EdgeNode* find_no_visited(EdgeNode* first_node){

    EdgeNode* edge_node = first_node;
    Node* node = first_node->first_node;

    while(node->no != -1){
        cout<<node->no<<endl; 
        if(!visited[node->no]){
            while(edge_node){
                if(edge_node->first_node->no == node->no){
                    return edge_node;
                }
                edge_node = edge_node->next; 
            }   
        }
        node = node->next;
    } 
    cout<<endl;
    return NULL;
} 

/**
*   邻接链表 DFS 
*   非递归方式实现 
*/ 
void DFS0(EdgeNode* graph){
    EdgeNode* tmp = graph;
    stack<EdgeNode*> stk;
    Node* node = tmp->first_node;
    stk.push(tmp);
    cout<<"编号:"<<node->no<<endl;
    visited[node->no] = true;
    while(!stk.empty()){
        tmp = stk.top();
        EdgeNode* no_visited =  find_no_visited(tmp);
        if(no_visited->next!= NULL) {
            cout<<"编号:"; 
            cout<<no_visited->first_node->no<<endl;
            visited[no_visited->first_node->no] = true; 
            stk.push(no_visited);
        }else{
            stk.pop();
        }
    }

}


int main(int argc, char** argv) {
//  EdgeNode* graph = init_graph();
//  visited[0] = true;
//  visited[1] = true;
//  visited[2] = true;
//  visited[3] = true;
//  visited[4] = true;
//  visited[5] = true;
//  visited[6] = true;
//  cout<<find_no_visited(graph)->first_node->no;
    DFS(init_graph());
    system("pause");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值