第十二周 项目4 利用遍历思想求解图问题(输出所有路径 )

/*        
 *          烟台大学计算机与控制工程学院       
 *文件名称:mian.cpp       
 *作    者:王旭       
 *完成日期:2015年11月19日       
 *版 本 号:v1.0     
 *       
 *问题描述: 输出从顶点u到v的所有简单路径。
  
 *            
 *输入描述:无
 *程序输出:无
 */  
mian.cpp:
<pre name="code" class="cpp">#include <stdio.h>
#include <malloc.h>
#include "graph.h"
int visited[MAXV];     //定义存放节点的访问标志的全局数组
void FindPaths(ALGraph *G,int u,int v,int path[],int d)
{
    int w,i;
    ArcNode *p;
    visited[u]=1;
    d++;            //路径长度增1,d是到当前为止已走过的路径长度,调用时初值为-1
    path[d]=u;              //将当前顶点添加到路径中
    if (u==v && d>1)            //输出一条路径
    {
        printf("  ");
        for (i=0; i<=d; i++)
            printf("%d ",path[i]);
        printf("\n");
    }
    p=G->adjlist[u].firstarc; //p指向u的第一条边
    while(p!=NULL)
    {
        w=p->adjvex;     //w为u的邻接顶点
        if (visited[w]==0)      //若顶点未标记访问,则递归访问之
            FindPaths(G,w,v,path,d);
        p=p->nextarc; //找u的下一个邻接顶点
    }
    visited[u]=0;   //恢复环境
}


void DispPaths(ALGraph *G,int u,int v)
{
    int i;
    int path[MAXV];
    for (i=0; i<G->n; i++)
        visited[i]=0; //访问标志数组初始化
    printf("从%d到%d的所有路径:\n",u,v);
    FindPaths(G,u,v,path,-1);
    printf("\n");
}

int main()
{
    ALGraph *G;
    int A[5][5]=
    {
        {0,1,0,1,0},
        {1,0,1,0,0},
        {0,1,0,1,1},
        {1,0,1,0,1},
        {0,0,1,1,0}
    };  //请画出对应的有向图
    ArrayToList(A[0], 5, G);
    DispPaths(G, 1, 4);
    return 0;
}


 graph.cpp,graph.h: 
#include <stdio.h>
#include <malloc.h>
#include "graph.h"
void ArrayToList(int *Arr, int n, ALGraph *&G)
{
    int i,j,count=0;  //count用于统计边数,即矩阵中非0元素个数
    ArcNode *p;
    G=(ALGraph *)malloc(sizeof(ALGraph));
    G->n=n;
    for (i=0; i<n; i++)                 //给邻接表中所有头节点的指针域置初值
        G->adjlist[i].firstarc=NULL;
    for (i=0; i<n; i++)                 //检查邻接矩阵中每个元素
        for (j=n-1; j>=0; j--)
            if (Arr[i*n+j]!=0)      //存在一条边,将Arr看作n×n的二维数组,Arr[i*n+j]即是Arr[i][j]
            {
                p=(ArcNode *)malloc(sizeof(ArcNode));   //创建一个节点*p
                p->adjvex=j;
                p->info=Arr[i*n+j];
                p->nextarc=G->adjlist[i].firstarc;      //采用头插法插入*p
                G->adjlist[i].firstarc=p;
            }

    G->e=count;
}


#ifndef GRAPH_H_INCLUDED
#define GRAPH_H_INCLUDED

#define MAXV 100                //最大顶点个数
#define INF 32767       //INF表示∞
typedef int InfoType;

//以下定义邻接矩阵类型
typedef struct
{
    int no;                     //顶点编号
    InfoType info;              //顶点其他信息,在此存放带权图权值
} VertexType;                   //顶点类型

typedef struct                  //图的定义
{
    int edges[MAXV][MAXV];      //邻接矩阵
    int n,e;                    //顶点数,弧数
    VertexType vexs[MAXV];      //存放顶点信息
} MGraph;                       //图的邻接矩阵类型

//以下定义邻接表类型
typedef struct ANode            //弧的结点结构类型
{
    int adjvex;                 //该弧的终点位置
    struct ANode *nextarc;      //指向下一条弧的指针
    InfoType info;              //该弧的相关信息,这里用于存放权值
} ArcNode;

typedef int Vertex;

typedef struct Vnode            //邻接表头结点的类型
{
    Vertex data;                //顶点信息
    int count;                  //存放顶点入度,只在拓扑排序中用
    ArcNode *firstarc;          //指向第一条弧
} VNode;

typedef VNode AdjList[MAXV];    //AdjList是邻接表类型

typedef struct
{
    AdjList adjlist;            //邻接表
    int n,e;                    //图中顶点数n和边数e
} ALGraph;                      //图的邻接表类型

void ArrayToMat(int *Arr, int n, MGraph &g); //用普通数组构造图的邻接矩阵
void ArrayToList(int *Arr, int n, ALGraph *&); //用普通数组构造图的邻接表
void MatToList(MGraph g,ALGraph *&G);//将邻接矩阵g转换成邻接表G
void ListToMat(ALGraph *G,MGraph &g);//将邻接表G转换成邻接矩阵g
void DispMat(MGraph g);//输出邻接矩阵g
void DispAdj(ALGraph *G);//输出邻接表G

#endif // GRAPH_H_INCLUDED


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用DJ算法解决21个城市之间的最短路径问题的Matlab代码: ```matlab % 城市距离矩阵 D = [0 17 32 46 32 19 25 18 42 31 29 31 42 25 36 28 27 42 38 22 11; 17 0 15 30 22 3 8 15 25 16 15 18 27 10 22 13 14 25 21 6 8; 32 15 0 15 35 18 9 28 12 20 17 23 14 18 9 17 23 13 7 23 23; 46 30 15 0 50 32 25 42 24 37 34 41 24 32 26 32 38 17 16 35 39; 32 22 35 50 0 19 30 19 54 47 45 45 53 36 47 40 39 54 49 33 23; 19 3 18 32 19 0 6 12 22 14 14 16 25 8 19 10 11 22 18 3 5; 25 8 9 25 30 6 0 21 10 13 12 14 20 5 16 7 9 20 16 5 8; 18 15 28 42 19 12 21 0 47 38 36 36 45 28 39 31 30 45 41 25 15; 42 25 12 24 54 22 10 47 0 25 22 29 12 24 17 23 29 9 5 31 34; 31 16 20 37 47 14 13 38 25 0 4 8 19 13 6 6 12 17 12 16 22; 29 15 17 34 45 14 12 36 22 4 0 7 20 11 3 5 11 13 9 13 19; 31 18 23 41 45 16 14 36 29 8 7 0 23 12 10 13 17 15 11 15 19; 42 27 14 24 53 25 20 45 12 19 20 23 0 18 10 16 22 4 7 33 32; 25 10 18 32 36 8 5 28 24 13 11 12 18 0 12 4 5 16 12 3 10; 36 22 9 26 47 19 16 39 17 6 3 10 10 12 0 10 16 10 6 24 27; 28 13 17 32 40 10 7 31 23 6 5 13 16 4 10 0 2 15 11 12 18; 27 14 23 38 39 11 9 30 29 12 11 17 22 5 16 2 0 19 15 17 21; 42 25 13 17 54 22 20 45 9 17 13 15 4 16 10 15 19 0 4 29 32; 38 21 7 16 49 18 16 41 5 12 9 11 7 12 6 11 15 4 0 26 29; 22 6 23 35 33 3 5 25 31 16 13 15 33 3 24 12 17 29 26 0 12; 11 8 23 39 23 5 8 15 34 22 19 19 32 10 27 18 21 32 29 12 0]; % DJ算法求解最短路径 n = size(D, 1); % 城市数目 S = zeros(1, n); % S集合,表示已遍的城市 S(1) = 1; % 从第一个城市开始遍 d = Inf(1, n); % d数组,表示起点到各个城市的距离 d(1) = 0; % 起点到自身的距离为0 for i = 2:n % 初始化d数组 d(i) = D(1, i); end for i = 2:n % 遍n-1个城市 minDist = Inf; % 最短距离初始化为无穷大 for j = 2:n % 在未遍的城市中寻找距离最短的城市 if S(j) == 0 && d(j) < minDist minDist = d(j); u = j; end end S(u) = 1; % 标记该城市已遍 for v = 2:n % 更新d数组 if S(v) == 0 && d(v) > d(u) + D(u, v) d(v) = d(u) + D(u, v); end end end % 输出最短路径和距离 path = [1]; % 路径数组,初始化为起点 dist = 0; % 距离初始化为0 while length(path) < n % 遍所有城市 minDist = Inf; % 最短距离初始化为无穷大 for i = 2:n % 在未遍的城市中寻找距离最短的城市 if S(i) == 0 && d(i) < minDist minDist = d(i); u = i; end end S(u) = 1; % 标记该城市已遍 path = [path u]; % 将该城市加入路径 dist = dist + D(path(end-1), path(end)); % 更新距离 end dist = dist + D(path(end), path(1)); % 加上回到起点的距离 disp('最短路径:'); disp(path); disp('最短距离:'); disp(dist); ``` 这段代码中,我们首先定义了城市距离矩阵 `D`,然后使用DJ算法求解最短路径。在求解过程中,我们使用了两个数组 `S` 和 `d`,分别表示已遍的城市和起点到各个城市的距离。在每次遍时,我们选择距离起点最近的未遍城市作为下一个遍的城市,并更新 `d` 数组。最后,我们根据 `S` 和 `d` 数组求出最短路径和距离。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值