zoukankan      html  css  js  c++  java
  • 数据结构之图

    • 实现有向图、无向图、有权图、无权图的邻接矩阵和邻接表表示方法
    • 实现图的深度优先搜索、广度优先搜索
    • 实现Dijkstra算法、A*算法
    • 实现拓扑排序的Kahn算法、DFS算法

     #include<stdio.h>
    #include<iostream>
    #include<stdlib.h>
    #include<limits.h>
    #include<iomanip>
     
    using namespace std;
     
    #define TRUE 1
    #define FALSE 0
    #define OK 1
    #define ERROR 0
    #define OVERFLOW -2
    #define INFINITY INT_MAX //最大值
    #define MAX_VERTEX_NUM 20 //最大顶点个数
    typedef int Status;
    typedef int VRType;
    typedef int InfoType;
    //{有向图,有向网,无向图,无向网}
    typedef enum{DG,DN,UDG,UDN}GraphKind;
     
    typedef struct ArcCell {
        VRType adj;//VRType是顶点关系类型。对无权图,用1或0
        //表示相邻否;对带权图,则为权值类型
        InfoType *info;//该弧相关信息的指针
    }ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
     
    typedef char VertexType;
    typedef struct {
        VertexType vexs[MAX_VERTEX_NUM];//顶点向量
        AdjMatrix arcs;//邻接矩阵
        int vexnum, arcnum;//图的当前顶点数和弧数
        GraphKind kind;//图的种类标志
    }MGraph;
     
    //在G中找到v对应的顶点位置
    int LocateVex(MGraph G, char v)
    {
        int i;
        for (i = 0; i < G.vexnum; i++)
        {
            if (G.vexs[i] == v)
            {
                return i;
            }
        }
        return -1;
    }
     
    /*
      算法7.2
      采用数组(邻接矩阵)表示法,构造无向网G
    */
    Status CreateUDN(MGraph &G)
    {
        int i, j, k, w;
        VertexType v1, v2;
        cout << "输入顶点数G.vexnum:";
        cin >> G.vexnum;
        cout << "输入边数G.arcnum:";
        cin >> G.arcnum;
        getchar();
        for (i = 0; i < G.vexnum; i++)
        {
            cout << "输入顶点G.vexs[" << i << "]" << endl;
            cin >> G.vexs[i];
            getchar();
        }//构造顶点向量
     
        //初始化邻接矩阵
        for (i = 0; i < G.vexnum; i++)
        {
            for (j = 0; j < G.vexnum; j++)
            {
                G.arcs[i][j].adj = INFINITY;
                G.arcs[i][j].info = NULL;
            }
        }
        //构造邻接矩阵
        for (k = 0; k < G.arcnum; ++k)
        {
            cout << "输入第" << k + 1 << "条边vi、vj和权值w(int):" << endl;
            //输入一条边依附的顶点及权值
            cin >> v1;
            cin >> v2;
            cin >> w;
            getchar();
            //确定v1和v2在G中的位置
            i = LocateVex(G, v1);
            j = LocateVex(G, v2);
            G.arcs[i][j].adj = w;//弧<v1,v2>的权值
            //置<v1,v2>的对称弧<v2,v1>
            G.arcs[j][i].adj = G.arcs[i][j].adj;
         }
        return OK;
    }
     
    Status CreateDN(MGraph &G)
    {
        int i, j, k, w;
        VertexType v1, v2;
        cout << "输入顶点数G.vexnum:";
        cin >> G.vexnum;
        cout << "输入边数G.arcnum:";
        cin >> G.arcnum;
        getchar();
        for (i = 0; i < G.vexnum; i++)
        {
            cout << "输入顶点G.vexs[" << i << "]" << endl;
            cin >> G.vexs[i];
            getchar();
        }//构造顶点向量
     
         //初始化邻接矩阵
        for (i = 0; i < G.vexnum; i++)
        {
            for (j = 0; j < G.vexnum; j++)
            {
                G.arcs[i][j].adj = INFINITY;
                G.arcs[i][j].info = NULL;
            }
        }
        //构造邻接矩阵
        for (k = 0; k < G.arcnum; ++k)
        {
            cout << "输入第" << k + 1 << "条边vi、vj和权值w(int):" << endl;
            //输入一条边依附的顶点及权值
            cin >> v1;
            cin >> v2;
            cin >> w;
            getchar();
            //确定v1和v2在G中的位置
            i = LocateVex(G, v1);
            j = LocateVex(G, v2);
            G.arcs[i][j].adj = w;//弧<v1,v2>的权值
        }
        return OK;
    }
    /*
    有向图的构造
    */
    Status CreateDG(MGraph &G)
    {
        int i, j, k, w;
        VertexType v1, v2;
        cout << "输入顶点数G.vexnum:";
        cin >> G.vexnum;
        cout << "输入边数G.arcnum:";
        cin >> G.arcnum;
        getchar();
        for (i = 0; i < G.vexnum; i++)
        {
            cout << "输入顶点G.vexs[" << i << "]" << endl;
            cin >> G.vexs[i];
            getchar();
        }//构造顶点向量
     
         //初始化邻接矩阵
        for (i = 0; i < G.vexnum; i++)
        {
            for (j = 0; j < G.vexnum; j++)
            {
                G.arcs[i][j].adj = 0;
                G.arcs[i][j].info = NULL;
            }
        }
        //构造邻接矩阵
        for (k = 0; k < G.arcnum; ++k)
        {
            cout << "输入第" << k + 1 << "条边vi、vj:" << endl;
            cin >> v1;
            cin >> v2;
            getchar();
            //确定v1和v2在G中的位置
            i = LocateVex(G, v1);
            j = LocateVex(G, v2);
            G.arcs[i][j].adj = 1;//1代表可达,0代表不可达
        }
        return OK;
    }
    /*
    无向图的构造
    */
    Status CreateUDG(MGraph &G)
    {
        int i, j, k, w;
        VertexType v1, v2;
        cout << "输入顶点数G.vexnum:";
        cin >> G.vexnum;
        cout << "输入边数G.arcnum:";
        cin >> G.arcnum;
        getchar();
        for (i = 0; i < G.vexnum; i++)
        {
            cout << "输入顶点G.vexs[" << i << "]" << endl;
            cin >> G.vexs[i];
            getchar();
        }//构造顶点向量
     
         //初始化邻接矩阵
        for (i = 0; i < G.vexnum; i++)
        {
            for (j = 0; j < G.vexnum; j++)
            {
                G.arcs[i][j].adj = 0;
                G.arcs[i][j].info = NULL;
            }
        }
        //构造邻接矩阵
        for (k = 0; k < G.arcnum; ++k)
        {
            cout << "输入第" << k + 1 << "条边vi、vj:" << endl;
            cin >> v1;
            cin >> v2;
            getchar();
            //确定v1和v2在G中的位置
            i = LocateVex(G, v1);
            j = LocateVex(G, v2);
            G.arcs[i][j].adj = 1;//1代表可达,0代表不可达
            G.arcs[j][i].adj = G.arcs[i][j].adj;
        }
        return OK;
    }
    /*
    算法7.1
    采用数组(邻接矩阵)表示法,构造图G。
    */
    Status CreateGraph(MGraph &G)
    {
        cout << "请输入图的种类:0表示DG,1表示DN,2表示UDG,3表示UDN" << endl;
        int x;
        cin >> x;
        G.kind=(GraphKind)x;
        switch (G.kind)
        {
        case DG:
            return CreateDG(G);
        case DN:
            return CreateDN(G);
        case UDG:
            return CreateUDG(G);
        case UDN:return CreateUDN(G);
        default:return ERROR;
        }
    }
     
    void list(MGraph G)
    {
        int i, j;
        cout << "输出邻接矩阵:" << endl;
        for (i = 0; i < G.vexnum; ++i)
        {
            cout << G.vexs[i] << "----";
            for (j = 0; j < G.vexnum; ++j)
            {
                if (G.arcs[i][j].adj == INFINITY)
                    cout << setw(4) << "∞";
                else
                    cout << setw(4) << G.arcs[i][j].adj;            
            }
            cout << endl;
        }
    }
     
    void main()
    {
        MGraph G;
        int x=1;
        while (x)
        {
            CreateGraph(G);
            list(G);
            cout << "是否继续(1、继续,0、退出)";
                cin >> x;
                cout << endl;
        }
        system("pause");
    }

  • 相关阅读:
    为什么电影里的黑客都不屑用鼠标? (转)
    专注做好一件事(转) focus---这个世界上最成功的人,他们在某一领域获得成功之后,可通过经营杠杆进入任何他们想要涉足的领域。而这都得依赖于他们曾极致的专注在做好一件事情上。
    世间万物都是遵循某种类似的规律,谁先把握了这些规律,谁就最早成为了强者。
    走的时候不要太急,有时间要停下来想一想当初为什么而走,这样,才会走的更稳,走的更明白。
    Android笔记: Android版本号
    Android笔记:真机调试无法输出Log 信息的问题
    阿里云服务器试用
    Android笔记:利用InputStream和BufferedReader 进行字节流 字符流处理
    Android笔记:java 中的数组
    Android笔记:C memory copy
  • 原文地址:https://www.cnblogs.com/hrnn/p/13347236.html
Copyright © 2011-2022 走看看