【数据结构】图-最短路径算法

简介: 【数据结构】图-最短路径算法

图的最短算法

从起点开始访问所有路径,可以到达终点的有多条地址,其中路径权值最小的为最短路径。
最短路径算法有深度优先遍历、广度优先遍历、Bellman-Ford算法、弗洛伊德算法、SPFA(Shortest Path Faster Algorithm)算法和迪杰斯特拉算法等。

本代码使用深度优先遍历

主要实现思路

从起点开始,到达终点有多条分支,这些分支中又有多条分支...
选择其实一条分支,走到终点,再选择另一个分支(temp = temp ->next)走到终点,分支的分支......

大致流程:
在这里插入图片描述代码实现:

#include<iostream>
#include<queue>
using namespace std;

/*
    邻接列表的大致排列类似于哈希表
    自己定义出"邻接桶"的概念,类似于“哈希桶”
    邻接桶中存着每个顶点
    每个顶点的通过EdgeNode——边,来链接着顶点和顶点,
    每个顶点都可以作为起始点,指向/被指向。


    这个容器就是“邻接桶”
                           *
    *            *            *
    *            **************    
    *            *            *
    *            *           *
    *            *    
    *            *    
    *            *    
    *            *           *
    *            *            *
    *            **************    
    *            *            *
    *            *           *    
    *            *    
    *            *    
    *            *    
    *            *    
    *            *           *
    *            *            *
    *            **************    
    *            *            *
    *            *           *
    *            *    
    *            *    
    *            *    
    *    顶点    *    
    *            *    
    *            *    
    ************
*/
#define Max_Size 1024 
bool visited[Max_Size];
typedef struct _EdgeNode
{
    int adjvex;
    int weight;
    struct _EdgeNode* next;
}EdgeNode;

typedef struct _VertexNode//顶点结点,这个就是邻接桶
{
    char data;//结点数据
    struct _EdgeNode* first;//指向邻接第一条边
}VertexNode, AdjList;

typedef struct _AdjListGraph
{
    AdjList* adjlist;
    int vex;//顶点数
    int edge;//边数

}AdjListGraph;

//通过顶点对应的字符来寻找顶点在图中的邻接点
int Location(AdjListGraph& G,char c)
{
    for (int i = 0; i < G.vex; i++)
    {
        if (G.adjlist[i].data == c)
        {
            return i;
        }
    }
    return -1;
}

//图的初始化
void initGraph(AdjListGraph& G)
{
    G.adjlist = new AdjList[Max_Size];//左侧的邻接桶
    G.edge = 0;
    G.vex = 0;
    
    for (int i = 0; i < Max_Size; i++)
    {
        visited[i] = false;    
    }
}

//图的创建
void createGraph(AdjListGraph& G)
{
    cout << "请输入该图的顶点数以及边数" << endl;
    cin >> G.vex >> G.edge;
    cout << "请输入顶点data" << endl;
    for (int i = 0; i < G.vex; i++)
    {
        cin >> G.adjlist[i].data;//输入顶点所存数据
        G.adjlist[i].first = NULL;//边和边的关系,置空,先不与任何边相连。
    }    


    //确定顶点与顶点之间的关系,两个顶点形成一条边,有几条边,就有几对i1 i2

    char v1 = 0, v2 = 0;//保存输入的顶点的字符
    int i1 = 0, i2 = 0;//保存顶点在数组中的下标
    //将i1和i2链接起来
    //i1为起点。i2为终点。

    //保存边的权重
    int weight = 0;

    cout << "请输入想关联边的顶点" << endl;
    for (int i = 0; i < G.edge; i++)
    {
        cin >> v1 >> v2 >> weight;//以v1为起点,v2为终点的边,权重是weight
        i1 = Location(G, v1);
        i2 = Location(G, v2);
        //说明存在
        if (i1 != -1 && i2 != -1)
        {
            EdgeNode* temp = new EdgeNode;
            temp->adjvex = i2;
            temp->next = G.adjlist[i1].first;//头插法-类似于hashtable中的插入数据
            temp->weight = weight;
            G.adjlist[i1].first = temp;
        }
    }
}

//图的最短路径算法

int min_weight = 0x7FFFFFFF;//定义一个最大的方便与之比较。(INT_MAX)
int steps = 0;//已走过的步数
int path[Max_Size ] = { 0 };//保存走过的路径
int shortest_path[Max_Size] = { 0 };//保存最短路径

//求图的最短路径——深度优先遍历(前提是连通图)
//                            起点   终点      已走过的权重和   
void DFS(AdjListGraph& G,int start ,int end,int weights)
{
    int cur = -1;

    if (start == end)//已经找到终点了,不需要遍历了
    {
        for (int i = 0; i < steps; i++)
        {
            cout << G.adjlist[path[i]].data << " ";//path中存的是对应结点在邻接桶中的下标,通过这个下标就能找到对应的data,即可找到走过的路径
        }    
        cout << "该路径对应的长度是:" << weights << endl;//输入对应的路径长度

        if (min_weight > weights)//取到当前最小路径
        {
            min_weight = weights;
            memcpy(shortest_path, path, steps * sizeof(int));
        }
        return;
    }
    visited[start] = 1;
    EdgeNode* temp = G.adjlist[start].first;//指向第一条边

    while (temp)
    {
        int weight = temp->weight;
        cur = temp->adjvex;//通过这条边的指向,指过来的这个顶点,在邻接桶中的下标
        if (!visited[cur])
        {
            visited[cur] = 1;//标记已经访问
            path[steps++] = cur;
            //递归
            DFS(G, cur, end, weights+weight);

            visited[cur] = 0;//前一步探索完成后,置空cur,(应该是有路线含有重复结点时起到作用)
            path[--steps] = 0;//路径回退
        }
        temp = temp->next;
    }
}

int main(void)
{
    AdjListGraph G;
    //初始化
    initGraph(G);
    //创建图
    createGraph(G);
    //深度优先-寻找最短路径
    DFS(G, Location(G, 'A'), Location(G, 'D'), 0);
    cout << "成功得到最短路径为" << endl;
    //最短路径
    int i = 0;
    cout << "起点";
    while (shortest_path[i] > 0 && i < Max_Size)
    {
        cout << "->" << G.adjlist[shortest_path[i]].data ;
        i++;
    }
    cout << endl;
    return 0;

}

输入示例
在这里插入图片描述

相关文章
|
17天前
|
算法 数据处理 C语言
C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
28 1
|
21天前
|
机器学习/深度学习 算法 数据挖掘
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构。本文介绍了K-means算法的基本原理,包括初始化、数据点分配与簇中心更新等步骤,以及如何在Python中实现该算法,最后讨论了其优缺点及应用场景。
65 4
|
2月前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
91 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
18天前
|
存储 算法 搜索推荐
Python 中数据结构和算法的关系
数据结构是算法的载体,算法是对数据结构的操作和运用。它们共同构成了计算机程序的核心,对于提高程序的质量和性能具有至关重要的作用
|
18天前
|
数据采集 存储 算法
Python 中的数据结构和算法优化策略
Python中的数据结构和算法如何进行优化?
|
26天前
|
算法
数据结构之路由表查找算法(深度优先搜索和宽度优先搜索)
在网络通信中,路由表用于指导数据包的传输路径。本文介绍了两种常用的路由表查找算法——深度优先算法(DFS)和宽度优先算法(BFS)。DFS使用栈实现,适合路径问题;BFS使用队列,保证找到最短路径。两者均能有效查找路由信息,但适用场景不同,需根据具体需求选择。文中还提供了这两种算法的核心代码及测试结果,验证了算法的有效性。
88 23
|
26天前
|
算法
数据结构之蜜蜂算法
蜜蜂算法是一种受蜜蜂觅食行为启发的优化算法,通过模拟蜜蜂的群体智能来解决优化问题。本文介绍了蜜蜂算法的基本原理、数据结构设计、核心代码实现及算法优缺点。算法通过迭代更新蜜蜂位置,逐步优化适应度,最终找到问题的最优解。代码实现了单链表结构,用于管理蜜蜂节点,并通过适应度计算、节点移动等操作实现算法的核心功能。蜜蜂算法具有全局寻优能力强、参数设置简单等优点,但也存在对初始化参数敏感、计算复杂度高等缺点。
58 20
|
17天前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
46 1
|
26天前
|
机器学习/深度学习 算法 C++
数据结构之鲸鱼算法
鲸鱼算法(Whale Optimization Algorithm,WOA)是由伊朗研究员Seyedali Mirjalili于2016年提出的一种基于群体智能的全局优化算法,灵感源自鲸鱼捕食时的群体协作行为。该算法通过模拟鲸鱼的围捕猎物和喷出气泡网的行为,结合全局搜索和局部搜索策略,有效解决了复杂问题的优化需求。其应用广泛,涵盖函数优化、机器学习、图像处理等领域。鲸鱼算法以其简单直观的特点,成为初学者友好型的优化工具,但同时也存在参数敏感、可能陷入局部最优等问题。提供的C++代码示例展示了算法的基本实现和运行过程。
45 0
|
26天前
|
算法 vr&ar 计算机视觉
数据结构之洪水填充算法(DFS)
洪水填充算法是一种基于深度优先搜索(DFS)的图像处理技术,主要用于区域填充和图像分割。通过递归或栈的方式探索图像中的连通区域并进行颜色替换。本文介绍了算法的基本原理、数据结构设计(如链表和栈)、核心代码实现及应用实例,展示了算法在图像编辑等领域的高效性和灵活性。同时,文中也讨论了算法的优缺点,如实现简单但可能存在堆栈溢出的风险等。
39 0