zoukankan      html  css  js  c++  java
  • 图的遍历DFS与BFS(邻接表)

    #include "stdafx.h"
    #include <iostream>
    #include <fstream>
    #include <queue>
    #include <Windows.h>
    
    using namespace std;
    
    #define INFINITY INT_MAX
    #define MAX_VERTEX_NUM 20  //顶点最多个数
    #define LENGTH 5           //顶点字符长度
    
    //*********************************邻接表***********************************begin
    typedef char VertexType[LENGTH];
    typedef struct ArcNode
    {
        int adjvex;
        struct ArcNode* nextarc;
        int weight;
    }ArcNode;
    
    typedef struct VNode
    {
        VertexType data;
        ArcNode *firstarc;
    }VNode, AdjList[MAX_VERTEX_NUM];
    
    typedef struct
    {
        AdjList vertices;
        int vexnum;
        int arcnum;
    }ALGraph;
    
    int LocateVex(const ALGraph & g, char name[LENGTH])
    {
        for (int i = 0; i < g.vexnum; i++)
        {
            if (0 == strcmp(g.vertices[i].data, name))
            {
                return i;
            }
        }
        return -1;
    }
    
    //图的建造
    void CreateGraph(ALGraph &g)
    {
        ifstream fcin(_T("graph.txt"));
        fcin>>g.vexnum;
        
        for (int i = 0; i < g.vexnum; i++)
        {
            fcin>>g.vertices[i].data;
            g.vertices[i].firstarc = NULL;
        }
        fcin>>g.arcnum;
        char arcHead[LENGTH];
        char arcTail[LENGTH];
        int weight;
        ArcNode *p, *q;
        ArcNode *pTmp;
        for (int i = 0; i < g.arcnum; i++)
        {
            
            memset(arcHead, 0, LENGTH);
            memset(arcTail, 0, LENGTH);
            fcin>>arcTail>>arcHead>>weight;
            int x = LocateVex(g, arcHead);
            int y = LocateVex(g, arcTail);
            p = new ArcNode;
            q = new ArcNode;
            p->adjvex = y;
            p->nextarc = NULL;
            p->weight = weight;
            q->adjvex = x;
            q->nextarc = NULL;
            q->weight = weight;
            if (NULL == g.vertices[x].firstarc)
            { 
                g.vertices[x].firstarc = p;
            }
            else
            {
                for (pTmp = g.vertices[x].firstarc; NULL != pTmp->nextarc; pTmp = pTmp->nextarc)
                {
                    ;
                }
                pTmp->nextarc = p;
                
            }
            if (NULL == g.vertices[y].firstarc)
            { 
                g.vertices[y].firstarc = q;
            }
            else
            {
                for (pTmp = g.vertices[y].firstarc; NULL != pTmp->nextarc; pTmp = pTmp->nextarc)
                {
                    ;
                }
                pTmp->nextarc = q;
            }
            /*p->adjvex = y;
            p->nextarc = g.vertices[x].firstarc;
            p->weight = weight;
            g.vertices[x].firstarc = p;
    
            q->adjvex = x;
            q->nextarc = g.vertices[y].firstarc;
            q->weight = weight;
            g.vertices[y].firstarc = q;*/
        }
    }
    
    //v的第一个邻接点
    int FirstAdjVex(const ALGraph &g, int v)
    {
        if ( NULL != g.vertices[v].firstarc)
        {
            return g.vertices[v].firstarc->adjvex;
        }
        return -1;
    }
    
    //v相对于w的下一个邻接点
    int NextAdjVex(const ALGraph &g, int v, int w)
    {
        ArcNode *p;
        for (p = g.vertices[v].firstarc; NULL != p; p = p->nextarc)
        {
            if (p->adjvex == w && p->nextarc != NULL)
            {
                return p->nextarc->adjvex;
            }
        }
        return -1;
    }
    
    //*********************************邻接表***********************************end
    
    //深度优先遍历
    bool visit[MAX_VERTEX_NUM];
    
    void DFS (ALGraph& g, int v)
    {
        visit[v] = true;
        cout<<g.vertices[v].data<<'\t';
        for (int w = FirstAdjVex(g, v); w >= 0; w = NextAdjVex(g, v, w))
        {
            if (!visit[w])
            {
                DFS(g, w);
            }
        }
    }
    
    void DFSTraverse(ALGraph &g)
    {
        for (int v = 0; v < g.vexnum; v++)
        {
            visit[v] = false;
        }
        for (int v = 0; v < g.vexnum; v++)
        {
            if (!visit[v])
            {
                DFS(g, v);
            }
        }
        cout<<endl;
    }
    
    //广度优先遍历
    void BFSTraverse(ALGraph &g, char vName[LENGTH])
    {
        int pos = LocateVex(g, vName);
        for (int v = 0; v < g.vexnum; v++)
        {
            visit[v] = false;
        }
        queue<int> q;
        if (!visit[pos])
        {
            cout<<g.vertices[pos].data<<'\t';
            visit[pos] = true;
        }
        q.push(pos);
        while (!q.empty())
        {
            int v = q.front();
            q.pop();
            for (int w = FirstAdjVex(g, v); w >= 0; w = NextAdjVex(g, v, w))
            {
                if (!visit[w])
                {
                    cout<<g.vertices[w].data<<'\t';
                    visit[w] = true;
                    q.push(w);
                }
            }
        }
        cout<<endl;
    }
    
    //辅助函数,设置控制台的颜色
    void SetConsoleTextColor(WORD dwColor)
    {
        HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
        if (INVALID_HANDLE_VALUE == handle)
        {
            return;
        }
        SetConsoleTextAttribute(handle, dwColor);
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        ALGraph graph;
        CreateGraph(graph);
        SetConsoleTextColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
        cout<<"**************************DFS****************************"<<endl<<endl;
        DFSTraverse(graph);
        SetConsoleTextColor(FOREGROUND_GREEN | FOREGROUND_INTENSITY);
        cout<<"**************************BFS****************************"<<endl<<endl;
        BFSTraverse(graph, "V1");
        return 0;
    }

    界面运行如下:

    建造图的graph.txt文本内容如下:

    8
    V1 V2 V3 V4 V5 V6 V7 V8 
    10
    V1 V2 10
    V1 V3 50
    V2 V4 30
    V3 V5 40
    V3 V6 99
    V4 V5 2
    V4 V7 60
    V5 V7 80
    V6 V8 22
    V7 V8 70
  • 相关阅读:
    重启进程
    linux如何查看端口被哪个进程占用?
    Web服务器磁盘满深入解析及解决
    基于Nginx实现访问控制、连接限制
    Tomcat线程模型分析及源码解读
    linux防火墙使用以及配置
    MySQL死锁及解决方案
    tcpdump 命令
    netperf 网络性能测试
    netstat 命令详解
  • 原文地址:https://www.cnblogs.com/venow/p/2638911.html
Copyright © 2011-2022 走看看