数据结构--图(最短路径、深度优先遍历、邻接表的创建)

数据结构–图(最短路径、深度优先遍历、邻接表的创建)

  要求是将两个csv文件读取,分别包含城市的数据(名字,经纬度,国家等)和路线数据(出发城市,目的地,价格,时间等)。然后实现深度遍历,最短路径算法。
  ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200509201103916.png)
  ![在这里插入图片描述](https://img-blog.csdnimg.cn/2020050920111428.png)

首先创建相关结构体

#include<iostream>
#include<math.h>
#include<Windows.h>
#include<cstdlib>
using namespace std;
#define MAX 222
#define OK 1
float a[MAX][MAX];
typedef struct{
    float latitude;
    float longitude;
    }VerTexType;
typedef struct{
    string transport, other_information;
    float time, cost;//即边的权
    }OtherInfo;//边结点
typedef struct Route{
    int adjvex;
    string next;//该边所指向的顶点的位置
    struct Route* nextarc;//指向下一条边的指针
    OtherInfo info;//和边相关的信息 
    }Route;//顶点信息
typedef struct{
    VerTexType data;
    int tag;
    bool pass;
    string country;
    string city;
    Route* firstdes;
    }City, Cities[MAX];//邻接表 
typedef struct{
    Cities cities;
    int vexnum, arcnum;//图的当前顶点数和边数 
    }ALGraph;

接下来建图读文件(我是边建边读)

//找元素所处位置
int LocateVex(ALGraph G, string u){ 
   for (int i = 0; i < G.vexnum; i++)    {       
    if (u == G.cities[i].city)//好像不能用strcm
          return i;
}    
    return -1;
    }
//构建有向图(by CSV)邻接表
string v1[2000], v2[2000];
int Create(ALGraph& G){    
//确定顶点数和边数
    G.arcnum = 1975;
    G.vexnum = 199; 
//输入各点,构造表头结点表
     FILE* fp; 
     fopen_s(&fp,"E:\\数据结构练习\\实习1图\\RRoute\\RRoute\\cities. csv", "r") ;
     if (!fp)
     {
             printf("Error!\n"); 
             exit(0);    
      }
      char ch;
      float f; 
      int i = 0; 
      while (!feof(fp) && i < G.vexnum) 
      {
           ch = fgetc(fp);
           for (; ch != ','; ch = fgetc(fp))
           { 
                     G.cities[i].country += ch;
                             } 
           ch = fgetc(fp);
           for (; ch != ','; ch = fgetc(fp)) 
                  {            
                       G.cities[i].city += ch; 
                  } 
                                       fscanf_s(fp, "%f,", &f);        G.cities[i].data.latitude = f;        fscanf_s(fp, "%f,", &f);        G.cities[i].data.longitude = f;        G.cities[i].tag = i;        G.cities[i].firstdes = NULL;        ch = fgetc(fp);
                             i++;    }   
                  fclose(fp);
//构造邻接表
    FILE* fp1; 
    fopen_s(&fp1,"E:\\数据结构练习\\test\\routes.csv", "r");
    if (!fp1)
    {
            printf("Error!\n");
            exit(0); 
     }
     char ch1;
     float f1;
     int m = 0, n = 0;
     i = 0;
     while (!feof(fp) && i < G.arcnum)
     { 
           ch1 = fgetc(fp1); 
           for (; ch1 != ','; ch1 = fgetc(fp1))
           {
               v1[i] += ch1; 
           }
           ch1 = fgetc(fp1);
           for (; ch1 != ','; ch1 = fgetc(fp1))
           { 
               v2[i] += ch1;        
           }
           m = LocateVex(G, v1[i]), n = LocateVex(G, v2[i]); 
           Route* p1 = new Route;//生成一个新的边结点*p1 
           ch1 = fgetc(fp1);       //完善边界点的信息
           for (; ch1 != ','; ch1 = fgetc(fp1)) 
           { 
                p1->info.transport += ch1; 
           }//交通方式 
          fscanf_s(fp1, "%f,", &f1); 
          p1->info.time = f1;//时间  
          fscanf_s(fp1, "%f,", &f1);       
          p1->info.cost = f1;//价格
          ch1 = fgetc(fp1);  
          ch1 = fgetc(fp1); 
          for (; ch1 != '"'; ch1 = fgetc(fp1)) 
          { 
              p1->info.other_information += ch1;  
          }//其他信息 
          p1->adjvex = n;//邻接点序号为n 
          p1->nextarc = G.cities[m].firstdes; 
          G.cities[m].firstdes = p1;  
          i++;
          ch1 = fgetc(fp1);
    } 
fclose(fp1);
return OK;
}

然后就做深度优先遍历

int whether[MAX] = { 0 };
void DFS(ALGraph* G, int i)
{
    whether[i] = 1;
    cout << G->cities[i].city << "-->";
    Route* p = G->cities[i].firstdes;
    while (p)
    {
        if (whether[p->adjvex] == 0)
            DFS(G, p->adjvex);
            p = p->nextarc;
    }
}

呜呜呜,接下来就是快乐的最短路径了,要求做迪杰斯特拉算法

由于本人技术有限,只会做邻接矩阵的算法,所以我只能将表里面需要用到的数据先转成一个矩阵。QwQ

void trans(ALGraph G)
{
    int i, j;
    Route* p;
    for (i = 0; i <= G.vexnum; i++)//先初始化,全部赋值为9999
    {        
        for (j = 0; j <= G.vexnum; j++)
        {
            a[i][j] = 9999;
        }
     }
     for (i = 0; i < G.vexnum; i++)
     {      
         p = G.cities[i].firstdes; 
         while (p) 
         {
             if (a[i][p->adjvex] > p->info.cost)//确保a中为最小值 
             { 
                  a[i][p->adjvex] = p->info.cost; 
             }
             p = p->nextarc;
          } 
        }
}

接下来就可以进行了(●°u°●)​ 」

void Dijkstra(ALGraph G, float dist[][MAX])
{
    int depart, dest;
    string v, u;
    int from[MAX] = { 0 };
    //确定出发点和目的地
    cout << "从 到 :";
    cin >> v >> u;
    depart = LocateVex(G, v);
    dest = LocateVex(G, u);
    G.cities[depart].pass = true;
    //将pass初始化,并将cost的数据拷入dist里面
    for (int v = 0; v < G.vexnum; v++)
    {
        G.cities[v].pass = false;
        for (int h = 0; h < G.vexnum; h++)
        {
            dist[v][h] = a[v][h];
        }
        from[v] = depart;
        dist[v][v] = 0;
    } 
    //找最短路径
    for (int i = 0; i < G.vexnum; i++) 
   {
        int v = 0;
        double mincost = 9999;
        //find the point that is closest to the depart
        for (int w = 0; w < G.vexnum; w++)
        { 
           if (G.cities[w].pass == false)
                if (dist[depart][w] < mincost)
                {
                    v = w;
                    mincost = dist[depart][w];//将最短距离copy到mincost里 
                 }
        } 
       //update the dist
       G.cities[v].pass = true;
        for (int w = 0; w < G.vexnum; w++)
        { 
            if (G.cities[w].pass == false && mincost + a[v][w] < dist[depart][w])
            {
                dist[depart][w] = mincost + a[v][w];
                //拼接
                from[w] = v;
            }
        }
    } 
    //output
    int num = dest;  
    cout << G.cities[num].city << "<--";
    while (num != depart)
    { 
        cout << G.cities[from[num]].city << "<--";
        num = from[num];
    } 
    cout << endl;
    cout << dist[depart][dest] << endl;
}
int main() 
{
    ALGraph G;
    Create (G) ;
    DFS(&G, 0);
    float (*b)[MAX];//指向数组的指针
    b = new float[MAX][MAX];
    Dijkstra(G, b);
    delete[] b;
    return 0;
}

QwQ如果大佬们有更好的做法希望指导啊~

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值