图——DFS,BFS(邻接表)

DFS你可以当成树的先根遍历来做,BFS你可以当做树的层次遍历来做,这里因为图不一定是连通图,所以每个顶点都要尝试一下,用一个BOOL数组来表示这个顶点是否经历过遍历。

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

typedef  char VertexType;
typedef  int EdgeType;

const  int   MAXVEX = 100;

typedef  struct  EdgeNode//边表结点
{
    int adjvex;
    EdgeType weight;
    EdgeNode * next;
}EdgeNode;

typedef  struct  VertexNode//顶点表结点
{
    VertexType data;
    EdgeNode * firstedge;
}VertexNode,AdjList[MAXVEX];


typedef  struct  GraphAdjList//图
{
    AdjList  adjList;
    int numVertexes,numEdges;
}GraphAdjList;

EdgeNode * Buy_EdgeNode()
{
    EdgeNode * e = new EdgeNode();
    return e;
}


//无向图邻接表表示
void  CreateALGraph_Undirected(GraphAdjList * G)
{
    EdgeNode * e;
    int i,j,k;
    EdgeType w;
    cout<<"请输入顶点数和边数:"<<endl;
    cin>>G->numVertexes>>G->numEdges;
    cout<<"请输入顶点名称:"<<endl;
    for(i = 0;i < G->numVertexes;++i)//输入顶点
    {       
        cin>>G->adjList[i].data;
        G->adjList[i].firstedge = NULL;
    }
    
    for(k = 0;k < G->numEdges;++k)//完成邻接表的填写工作
    {
        printf("请输入边(vi,vj)上的下标i,下标j和权w:\n");
        cin>>i>>j>>w;
        e = Buy_EdgeNode();
        e->adjvex = j;
        e->weight = w;
        e->next = G->adjList[i].firstedge;
        G->adjList[i].firstedge = e;

        e = Buy_EdgeNode();
        e->adjvex = i;
        e->weight = w;
        e->next = G->adjList[j].firstedge;
        G->adjList[j].firstedge = e;
    }
}

//有向图邻接表表示
void  CreateALGraph_Directed(GraphAdjList * G)
{
    EdgeNode * e;
    int i,j,k;
    EdgeType w;
    cout<<"请输入顶点数和边数:"<<endl;
    cin>>G->numVertexes>>G->numEdges;
    cout<<"请输入顶点名称:"<<endl;
    for(i = 0;i < G->numVertexes;++i)//输入顶点
    {       
        cin>>G->adjList[i].data;
        G->adjList[i].firstedge = NULL;
    }
    
    for(k = 0;k < G->numEdges;++k)//完成邻接表的填写工作
    {
        printf("请输入边<vi,vj>上的下标i,下标j和权w:\n");
        cin>>i>>j>>w;
        e = Buy_EdgeNode();
        e->adjvex = j;
        e->weight = w;
        e->next = G->adjList[i].firstedge;
        G->adjList[i].firstedge = e;
    }
}


void  Show_ALGraph(GraphAdjList * G)
{
    for(int i = 0;i < G->numVertexes;++i)
    {
        cout<<G->adjList[i].data<<":  ";
        EdgeNode * e = G->adjList[i].firstedge;
        while(e)
        {
            cout<<G->adjList[e->adjvex].data<<"("<<e->weight<<")  ";
            e = e -> next;
        }
        cout<<endl;
    }
}


typedef  bool  Boolean;
Boolean  visited[MAXVEX];

//邻接表的DFS递归算法

void  DFS(GraphAdjList& G,int i)
{
    visited[i] = true;
    cout<< G.adjList[i].data<<"->";
    EdgeNode * p =  G.adjList[i].firstedge;
    while(p)
    {
        if(!visited[p->adjvex])
        {
            DFS(G,(p->adjvex));
        }
        p = p->next;        
    }
}

//邻接表的DFS遍历操作
void DFSTraverse(GraphAdjList& G)
{
    int i;
    for(i = 0;i < G.numVertexes;++i)
    {
        visited[i] = false;
    }
    for(i = 0;i < G.numVertexes;++i)
    {
        if(!visited[i])
        {
            DFS(G,i);
        }
    }
    cout<<endl;
}


//邻接表的BFS遍历操作
void BFSTraverse(GraphAdjList& G)
{
    queue<int> Q;
    int i,j;
    for(i = 0;i < G.numVertexes;++i)
    {
        visited[i] = false;
    }

    for(i = 0;i < G.numVertexes;++i)
    {
        if(!visited[i])
        {            
            visited[i] = true;
            Q.push(i);
            while(!Q.empty())
            {
                j =  Q.front();
               Q.pop();
               cout<< G.adjList[j].data<<"->";
               EdgeNode * p =  G.adjList[j].firstedge;
               while (p)
               {
                   if(!visited[p->adjvex])
                   {
                       visited[p->adjvex] = true;
                       Q.push(p->adjvex);
                   }
                   p = p->next;
               }        
            }
        }
    }
    cout<<endl;
}



int main()
{
    GraphAdjList *G = new GraphAdjList();
    CreateALGraph_Directed(G);
    Show_ALGraph(G);
    BFSTraverse(*G);
    DFSTraverse(*G);
    delete G;
}
### DFSBFS 算法在邻接表示的中的实现 #### 深度优先搜索 (DFS) 对于深度优先搜索,在邻接表示的中,可以通过递归或显式使用栈来实现。此方法适用于有向和无向。 ```c++ void DFS(ALGraph G, int v) { cout << "Visit node: " << v; visited[v] = true; EdgeNode* p = G.vertices[v].firstedge; while(p != NULL){ int w = p->adjvex; if(!visited[w]){ DFS(G,w); } p = p->next; } } ``` 为了初始化并调用上述函数: ```c++ void DFSTraverse(ALGraph &G) { memset(visited,false,sizeof(visited)); for(int i=0;i<G.vexnum;++i){ if (!visited[i]) { DFS(G,i); } } } ``` 这段代码展示了如何遍历整个,即使存在不连通的部分[^1]。 #### 广度优先搜索 (BFS) 广度优先搜索则通常借助队列完成层次化探索的任务。同样地,这里也给出基于C++语言的一个简单例子: ```c++ void BFS(ALGraph G,int v) { queue<int> q; q.push(v); memset(visited,false,sizeof(visited)); visited[v]=true; while(!q.empty()){ int u=q.front(); q.pop(); cout<<"Visit node:"<<u<<endl; EdgeNode *p=G.vertices[u].firstedge; while(p!=NULL){ int w=p->adjvex; if(!visited[w]){ q.push(w); visited[w]=true; } p=p->next; } } } void BFSTraverse(ALGraph& G) { memset(visited,false,sizeof(visited)); for(int i=0;i<G.vexnum;++i){ if(!visited[i]){ BFS(G,i); } } } ``` 通过这种方式,可以逐层访问所有可达节点,并记录下它们被首次发现的时间戳等信息。 这两种算法都可用于解决多种实际问题,比如寻找最短路径、检测环路以及构建最小生成树等问题。当处理大规模数据集时,选择合适的策略尤为重要——DFS适合于求解具有较深嵌套结构的问题;而BFS更适合用于计算两点间距离或者查找最近公共祖先等情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值