El funcionamiento de las cinco imágenes

Naturaleza experimental: experimento integral

Reclamación:

(1) Adopte la matriz de adyacencia / tabla de adyacencia para construir el gráfico;
(2) Adopte el método de búsqueda en profundidad / primero en amplitud para recorrer el gráfico;
(3) Implemente mediante programación el algoritmo de ruta más corta de Dijkstra.

propósito:

(1) Dominar la matriz de adyacencia y los métodos
de almacenamiento de la tabla de adyacencia del gráfico ; (2) Dominar el algoritmo transversal del gráfico;
(3) Dominar la aplicación práctica del gráfico: el algoritmo de la ruta más corta.

Código

#include <iostream>
using namespace std;

//***邻接矩阵***//
#define MaxInt 32767                 //表示极大值,即∞
#define MVNum 100                   //最大顶点数
bool visited[MVNum],visited2[MVNum];    //初始化标志数组,值为false
typedef int VertexType;         //假设顶点的数据类型为字符型
typedef int ArcType;                  //假设边的权值类型为整型
typedef struct{
    
    
  VertexType vexs[MVNum];               //顶点表
  ArcType arcs[MVNum][MVNum];       //邻接矩阵
  int vexnum,arcnum; //图的顶点数和边数
}AMGraph;

//***邻接表***//
typedef struct ArcNode  //边结点
{
    
    
    int adjvex; //该边所指向的顶点的位置
    struct ArcNode * nextarc;   //指向下一条边的指针
    int info; //和边相关的信息
}ArcNode;
typedef struct VNode    //顶点信息
{
    
    
    int data;
    ArcNode * firstarc; //指向第一条依附该顶点的边的指针
}VNode,AdjList [MVNum]; //AdjList表示邻接表类型
typedef struct
{
    
    
    AdjList vertices;
    int vexnum,arcnum; //图的当前顶点数和边数

}ALGraph;
int LocateVex(ALGraph G,int u); //返回顶点u在图G中的位置
void CreateUDG(ALGraph &G);//邻接表建立无向图
void DFS_AL(ALGraph &G,int v);//邻接表表示图的深度优先搜索遍历
void CreateUDN(AMGraph &G2);  //邻接矩阵法建立有向图
void DFS_AM(AMGraph &G2,int v); //邻接矩阵深度优先搜索遍历
void ShortestPath_DIJ(AMGraph G, int v0);   //Dijkstra算法
void Menu();  //文字菜单提示信息

int main()
{
    
    
    ALGraph G;
    AMGraph G2;
    Menu();
    int v=0,v0=0;
    int i;  //输入的数字
    cout<<"请输入操作代码:";
    cin>>i;
    while(true)
    {
    
    
        switch(i)
        {
    
    
            case 1:
                CreateUDG(G);
                break;
            case 2:
                DFS_AL(G,v);
                cout<<endl;
                break;
            case 3:
                CreateUDN(G2);
                break;
            case 4:
                DFS_AM(G2,v);
                cout<<endl;
                break;
            case 5:
                ShortestPath_DIJ(G2,v0);
                break;
            default:
                if(i<0)
                    return 0;
                else
                {
    
    
                    cout<<"输入的位置非法,请重新输入";
                    break;
                }
        }
        cout<<"请输入操作代码:";
        cin>>i;
    }
    return 0;
}
int LocateVex(ALGraph G,int u) //返回顶点u在图G中的位置
{
    
    
    int i;
    for (i = 0; i < G.vexnum; i++)
    {
    
    
        if (u == G.vertices[i].data)
        return i;
    }
    return 0;
}
int LocateVex(AMGraph G2,int u) //返回顶点u在图G中的位置
{
    
    
    for(int i=0; i<G2.vexnum; i++)
        if(u==G2.vexs[i])
            return i;
    return 0;
}
void CreateUDG(ALGraph &G)  //邻接表法
{
    
    
    cout<<"输入总顶点数,总边数:";
    cin>>G.vexnum>>G.arcnum;    //总顶点数,总边数
    cout<<"输入顶点值:";
    for(int i=0;i<G.vexnum;i++) //输入各点,构造表头结点表
    {
    
    
        cin>>G.vertices[i].data;    //输入顶点值
        G.vertices[i].firstarc=NULL;    //初始化表头结点的指针域为NULL
    }
    cout<<"输入每条边依附的两个顶点:"<<endl;
    for(int k=0;k<G.arcnum;++k) //输入各边,构造邻接表
    {
    
    
        int v1,v2;
        cin>>v1>>v2;    //输入一条边依附的两个顶点
        int i=LocateVex(G,v1); int j=LocateVex(G,v2);
        //确定v1和v2在G中位置,即顶点在G.vertices中的序号
        ArcNode *p1=new ArcNode; //生成一个新的边结点
        p1->adjvex=j;   //邻接点序号为j
        p1->nextarc=G.vertices[i].firstarc; G.vertices[i].firstarc=p1;
        //将新节点*p1插入v1的边表头部
        ArcNode *p2=new ArcNode; //生成另一个对称的新节点*p2
        p2->adjvex=i;   //邻接点序号为i
        p2->nextarc=G.vertices[j].firstarc; G.vertices[j].firstarc=p2;
        //将新节点p2插入顶点v1的边表头部
    }
    cout<<"创建成功"<<endl;
}
void DFS_AL(ALGraph &G,int v)
{
    
    //图G为邻接表类型,从第v个顶点出发深度优先搜索遍历图G
    cout<<v;visited[v]=true; //访问第v个顶点,并置访问标志数组相应分量值为true
    ArcNode *p=G.vertices[v].firstarc;   //p指向v的第一个边结点
    while(p!=NULL)  //边结点非空
    {
    
    
        int w=p->adjvex;    //表示w是v的邻接点
        if(!visited[w])
            DFS_AL(G,w); //如果w未访问,则递归调用DFS_AL
        p=p->nextarc;   //p指向下一个边结点
    }
}
void CreateUDN(AMGraph &G2)  //邻接矩阵法
{
    
    
    //采用邻接矩阵表示法,创建无向网G
    cout<<"输入总顶点数,总边数:";
    cin>>G2.vexnum>>G2.arcnum;  //输入总顶点数,总边数
    cout<<"输入顶点值:";
    for(int i = 0; i<G2.vexnum; ++i)
       cin>>G2.vexs[i];                         //依次输入顶点的信息
    for(int i = 0; i<G2.vexnum;++i) //初始化邻接矩阵,边的权值均为极大值
        for(int j = 0; j<G2.vexnum;++j)
            G2.arcs[i][j] = MaxInt;
    cout<<"输入每条边依附的顶点及权值:"<<endl;
    for(int k = 0; k<G2.arcnum;++k)
    {
    
     //构造邻接矩阵
      int v1,v2,w;
      cin>>v1>>v2>>w; //输入一条边依附的顶点及权值
      int i = LocateVex(G2, v1);
      int j = LocateVex(G2, v2);  //确定v1和v2在G中的位置
      G2.arcs[i][j] = w;  //边<v1, v2>的权值置为w2
      //取消下面注释即建立无向图
      //G2.arcs[j][i] = G2.arcs[i][j]; //置<v1, v2>的对称边<v2, v1>的权值为w
    }
    cout<<"创建成功"<<endl;
}
void DFS_AM(AMGraph &G2, int v){
    
      //图G2为邻接矩阵类型
  cout<<v;
  visited2[v] = true;   //访问第v个顶点
  for(int w = 0; w< G2.vexnum; w++) //依次检查邻接矩阵v所在的行
        if((G2.arcs[v][w]!=MaxInt) && (!visited2[w]))
            DFS_AM(G2, w);
      //w是v的邻接点,如果w未访问,则递归调用DFS
}
void ShortestPath_DIJ(AMGraph G, int v0)
{
    
    
    bool S[MVNum];int D[MVNum],Path[MVNum];
    //用Dijkstra算法求有向网G的v0顶点到其余顶点的最短路径
    int n=G.vexnum;                         //n为G中顶点的个数
    for(int v = 0; v<n; ++v)
    {
    
                   //n个顶点依次初始化
       S[v] = false;                    //S初始为空集
       D[v] = G.arcs[v0][v];            //将v0到各个终点的最短路径长度初始化
       if(D[v]< MaxInt)  Path [v]=v0; //v0和v之间有弧,将v的前驱置为v0
       else Path [v]=-1;                //如果v0和v之间无弧,则将v的前驱置为-1
    }
    S[v0]=true;                     //将v0加入S
    D[v0]=0;                        //源点到源点的距离为0
    /*―开始主循环,每次求得v0到某个顶点v的最短路径,将v加到S集―*/
    int v=0;
    for(int i=1;i<n; ++i)
    {
    
    //对其余n?1个顶点,依次进行计算
        int min= MaxInt;
        for(int w=0;w<n; ++w)
          if(!S[w]&&D[w]<min)
              {
    
    v=w; min=D[w];} //选择一条当前的最短路径,终点为v
        S[v]=true; //将v加入S
        for(int w=0;w<n; ++w)
           //更新从v0出发到集合V?S上所有顶点的最短路径长度
            if(!S[w]&&(D[v]+G.arcs[v][w]<D[w]))
            {
    
    
                D[w]=D[v]+G.arcs[v][w];     //更新D[w]
                Path [w]=v;                     //更改w的前驱为v
            }
    }
    cout<<"以v0为起点的图的最短路径为:"<<endl;
    for(int i=0;i<G.vexnum;i++)
    {
    
    
        cout<<"v0->v"<<i<<":";
        if(D[i]!=MaxInt) //可以到达
        {
    
    
            cout<<D[i]<<endl;
        }
        else
        {
    
    
            cout<<"不可达,无最短路径"<<endl;
        }
    }
}
void Menu()
{
    
    
    cout << "---------------------------" << endl;
    cout << "****by 夏日****" << endl;
    cout << "---------------------------" << endl;
    cout << "1-----邻接表建立无向图 "<< endl;
    cout << "2-----邻接表表示图的深度优先搜索遍历" << endl;
    cout << "3-----邻接矩阵建立有向图 "<< endl;
    cout << "4-----邻接矩阵表示图的深度优先搜索遍历" << endl;
    cout << "5-----迪杰斯特拉算法计算最短路径(先用邻接矩阵建立有向图)" << endl;
    cout << "   退出,输入一个负数!" << endl;
}

Salida de muestra

1. El establecimiento de la lista de adyacencia no está dirigido Figura
Inserte la descripción de la imagen aquí
2. La lista de adyacencia representa el recorrido de búsqueda en profundidad del gráfico
Inserte la descripción de la imagen aquí
3. El establecimiento de la matriz de adyacencia está dirigido Figura
Inserte la descripción de la imagen aquí
4. El recorrido de búsqueda en profundidad primero de la matriz de adyacencia
Inserte la descripción de la imagen aquí
5. Algoritmo de Dijkstra
Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/zss192/article/details/106458541
Recomendado
Clasificación