• C++实现矩阵图的遍历·最小生成树(prim,kruskal)·最短路径(Dijkstra,floyd)


    #include<iostream>
    #include <iomanip>
    #include <stack>
    #include <deque>
    #include <fstream>
    using namespace std;

    struct primnode
    {
    public:
     char begvex;
     char endvex;
     int lowcost;
    };
    struct adknode
    {
        int dist;//最近距离
     char way[50];//顶点数组
     int nodenum;//经过的顶点数

    };

    class Mgraph//邻接矩阵储存结构
    {
    public:
     Mgraph(){}
     ~Mgraph(){}
     void CreatMGraph();
     void DFS (int );//用递归实现
     void DFS1(int );//非递归
     void BFS(int );
     void print();
     void prim();
     int mini();
     int low();//最短距离函数的辅助函数
     int LocateVex(char);
     void kruskal();
     void Dijkstra();
     void Floyd();
    private:
     int number;//顶点数目
     int arcnum;//边的数目
     char vexs[50];
     int arcs[50][50];
     int visited[50];//便利时的辅助工具
     primnode closeedge[50];//prim
     adknode dist[50];//最短路径
     int D[20][20];//floyd算法距离
     int P[20][20][20];//floyd算法路径
     
    };
    int   Mgraph::LocateVex(char s)
    {
     for(int i=0;i<number;i++)
         if (vexs[i]==s)
       return i;
      return -1;
    }
    void Mgraph::print()
    {
     cout<<"顶点为: ";
     for(int k=0;k<number;k++)
      cout<<vexs[k];
     cout<<endl;
     for(int i=0;i<number;i++)
     {
      for(int j=0;j<number;j++)
       cout<<setw(6)<<left<<arcs[i][j]<<"   ";
       cout<<endl;
     }

     for(int m=0;m<number;m++)
      cout<<visited[m];
     cout<<endl;
    }

    void Mgraph::CreatMGraph()//图的邻接矩阵储存结构
    {
     char vex1,vex2;
     int i,j,k,m;
     cout<<"请输入定点数,边数:"<<endl;
     cin>>number>>arcnum;
     cout<<"请输入顶点(字符串类型):"<<endl;
     for(i=0;i<number;i++)
      cin>>vexs[i];
     for(i=0;i<number;i++)
      for(j=0;j<number;j++)
       arcs[i][j]=1000;
     for(k=0;k<arcnum;k++)
     {
      cout<<"请输入边的两个顶点及边的权值: "<<endl;
      cin>>vex1>>vex2>>m;
      i=LocateVex(vex1);
      j=LocateVex(vex2);
      arcs[i][j]=m;
      arcs[j][i]=m;
     }

    }

    void Mgraph::DFS(int i=0)//用递归实现
    {
     int j;
        cout<<vexs[i]<<"------>";
     visited[i]=1;
     for (j=0;j<number;j++)
     {
      if(!(arcs[i][j]==1000)&&!visited[j])
       DFS(j);
     }
     
     
    }
    void Mgraph::DFS1(int i=0)//非递归
    {
     stack<int> st;
     st.push(i);
     while(!st.empty())
     {
      int j=st.top();
      st.pop();
      cout<<vexs[j]<<"---->";
      visited[j]=1;
      for(int k=0;k<number;k++)
      {
       if((!(arcs[j][k]==1000))&&!visited[k])
        st.push(k);
       
      }
     }

    }
    void Mgraph::BFS(int i=0)//广度优先遍历
    {
     deque<int> de;
     de.push_back(i);
     cout<<vexs[i]<<"------>";
     visited[i]=1;
     while(!de.empty())
     {
      int k=de.front();
      for(int j=0;j<number;j++)
      {
       if(arcs[k][j]!=1000&&!visited[j])
       {
        cout<<vexs[j]<<"------>";
        visited[j]=1;

        de.push_back(j);
       }
        
      }
      de.pop_front();

     }

     
    }
    int Mgraph::mini()
    {
     static int i;
     int min=0;
     for (int j=0;j<number;j++)
     {
      if(!visited[j])
      {
       if (closeedge[min].lowcost>closeedge[j].lowcost)
       {
        min=j;
       }
      }
      


     }
     i=min;
     cout<<"包括边("<<closeedge[i].begvex<<","<<closeedge[i].endvex<<")";
     return i;
    }
    void Mgraph::prim()
    {
     char u;
     cout<<"请输入起始顶点:"<<endl;
        cin>>u;
     int i=LocateVex(u);
     visited[i]=1;
     for(int j=0;j<number;j++)
     {
      closeedge[j].begvex=u;
      closeedge[j].endvex=vexs[j];
      closeedge[j].lowcost=arcs[i][j];
     }
        for (int m=1;m<number;m++)
     {
      int n=mini();
      visited[n]=1;
      closeedge[n].lowcost=1000;
      for (int p=0;p<number;p++)
      {
       if(!visited[p])
       {
        if(arcs[p][n]<closeedge[p].lowcost)
        {
         closeedge[p].lowcost=arcs[p][n];
            closeedge[p].begvex=vexs[n];

        }
        

       }
       
      }

     }

    }
    void Mgraph::kruskal()
    {
     int a,b,k=0;
     int min=1000;
     int arcs1[20][20];
     for (int m=0;m<number;m++)
     visited[m]=m;//每一个顶点属于一颗树
        for (int i=0;i<number;i++)
      for(int j=0;j<number;j++)
       arcs1[i][j]=arcs[i][j];


     while (k<number-1)
     {
      min=1000;
      for (int i=0;i<number;i++)
      {
       for (int j=0;j<number;j++)
       {
        if (arcs1[i][j]<min)
        {
         a=i;
         b=j;
         min=arcs1[i][j];
         
        }

       }
      }
      if (visited[a]!=visited[b])
      {
       cout<<"包括边("<<vexs[a]<<","<<vexs[b]<<")";
       k++;
       for (int n=0;n<number;n++)
       {
        if (visited[n]==visited[b])
         visited[n]=visited[a];
       }


      }
      else
       arcs1[a][b]=arcs[b][a]=1000;

     }
     
    }
    /*int Mgraph::low()
    {
     int m=1000;
     int min=0;
        int j;
     for ( j=0;j<number;j++)
     {
      if(!visited[j])
      {
       if (m>dist[j].dist)
       {
        m=dist[j].dist;
        min=j;
       }
      }
     }
     j=min;
     return j;

    }*/
    void Mgraph::Dijkstra()
    {
      cout<<"请输入起始点"<<endl;
      char u;
      cin>>u;
      
      int i=LocateVex(u);
      visited[i]=1;
      for (int j=0;j<number;j++)
      {
       dist[j].dist=arcs[i][j];
       dist[j].nodenum=0;
      }
      for (j=1;j<number;j++)
      {
       //int m=low();
       int distance=1000;
       int min=0;
       for (int  n=0;n<number;n++)
       {
        if(!visited[n])
        {
         if (distance>dist[n].dist)
         {
          distance=dist[n].dist;
          min=n;
         }
        }
       }
       int m=min;


       visited[m]=1;
       for (n=0;n<number;n++)
       {
        if(!visited[n])
        {
         if((dist[m].dist+arcs[m][n])<dist[n].dist)
         {
          dist[n].dist=dist[m].dist+arcs[m][n];
          dist[n].nodenum=0;
          for (int x=0;x<dist[m].nodenum;x++)
          {
           dist[n].way[x]=dist[m].way[x];
           dist[n].nodenum++;
          }
          dist[n].way[dist[n].nodenum++]=vexs[m];

         }
         
        }
       }
       
      }
      //输出功能
      for (int n=0;n<number;n++)
      {
       if (n!=i)
       {
        if(dist[n].dist<1000)
        {
        cout<<vexs[i]<<"到"<<vexs[n]<<"的最近距离为:"<<dist[n].dist<<endl;
        cout<<"经过的顶点为:"<<vexs[i]<<"---->";
        for (int p=0;p<dist[n].nodenum;p++)
        {
         cout<<dist[n].way[p]<<"----->";
        }
           cout<<vexs[n]<<endl;
        }
        else
         cout<<vexs[i]<<"到"<<vexs[n]<<"没有通路"<<endl;
       }
      }
    }
    void Mgraph::Floyd()
    {
     int i,j,m,n;
     for ( i=0;i<number;i++)
      for ( j=0;j<number;j++)
       for (m=0;m<number;m++)
        P[i][j][m]=0;
       
     for ( i=0;i<number;i++)
      for ( j=0;j<number;j++)
      {
       D[i][j]=arcs[i][j];
       if(D[i][j]<1000)
       {
        P[i][j][i]=1;
        P[i][j][j]=1;
       }
      }

      for ( i=0;i<number;i++)
       for ( j=0;j<number;j++)
          for (m=0;m<number;m++)
          {
           if (i==j||j==m||i==m)
            continue;
           if (D[i][m]+D[m][j]<D[i][j])
           {
          D[i][j]=D[i][m]+D[m][j];
           for (n=0;n<number;n++)
           {
           P[i][j][n]=P[i][m][n]||P[m][j][n];
           }
           }
          }
         
      for ( i=0;i<number;i++)
       for ( j=0;j<number;j++)
       {
        if (D[i][j]<1000)
        {
         cout<<vexs[i]<<"到"<<vexs[j]<<"的最近距离为:"<<D[i][j]<<endl;
         cout<<"经过的顶点为:";
         for (m=0;m<number;m++)
         {
          if (P[i][j][m])
          {
           cout<<vexs[m]<<"------>";

          }
         }
         cout<<endl;


        }
        else
         if (i!=j)
         cout<<vexs[i]<<"到"<<vexs[j]<<"没有通路"<<endl;
       
       }


     


    }

    int main()
    {
      Mgraph g;
     g.CreatMGraph();
    // g.print();
    // g.DFS();
    // g.DFS1();
    // g.BFS();
    // g.prim();
    // g.kruskal();
    // g.Dijkstra();
    // g.print();
     g.Floyd();
     return 0;
    }

  • 相关阅读:
    JDBC之Statement 接口的测试(存在sql注入风险)
    Java操作数据库之JDBC增删改查
    Java实体类之间的映射(一对多关系)
    Java实体类之间的映射(一对一关系)
    yield(放弃、谦逊、礼让)
    daemon(守护、服务员)-t1.setDaemon(true)
    join当前线程等待指定的线程结束后才能继续运行
    检查你要加入到gradle的第三方library是否是最新版本
    git 无法忽略Android Studio 生成的 .idea目录解决办法
    mybatis3 step by step 快速上手
  • 原文地址:https://www.cnblogs.com/anning/p/1921179.html
Copyright © 2020-2023  润新知