关于Dijkstra(迪杰斯特拉)算法的总结与C语言实现

本文详细介绍了Dijkstra算法,包括算法描述、实例解析和关键要点。特别指出,该算法适用于非负权值图的单源最短路径问题,不适用于负权边。同时提供了邻接表和邻接矩阵两种数据结构的C++实现代码,帮助理解算法的执行过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        如题 自用笔记 如有错误欢迎及时指正

目录

一.算法描述

1).Dijkstra算法描述

2).例子

3).要点

二.可运行代码

1).邻接表实现

        (1).存储结构以及基本函数部分

        (2).算法实现部分

2).邻接矩阵实现

        (1).存储结构以及基本函数部分

        (2).算法实现部分


一.算法描述

        Dijkstra算法本质上是一种类似排序的方法,它的中心思想就是按路径权值递增次序求取最短路径,适用于图中边权值非负的单源最短路径的求解,先给出带权无向图G在邻接矩阵存储结构下的算法文字描述。

1).Dijkstra算法描述

2).例子

3).要点

        注意:该算法仅适用于权值非负的图求取单源最短路径,权值为负时需要用Floyd算法求解

        原因:在上面的算法描述可以看到,当把一个点vj选入集合S时,就意味着已经找到了从v0到vj点的最短路径,但是如果图中存在负权边时就不一定成立了。

        Eg:假设有一个顶点C,C只与A和B有边连接,从A到C的权为50,从C到B的权为-49,现在A到B的最短路径显然是A -> C -> B而不是A -> B,但是按Dijkstra算法处理这种情况时,最小权值路径的判断会出错。

        Dijkstra算法在邻接矩阵和邻接表存储结构下时间复杂度均为O(n^2),n为节点数。

二.可运行代码

1).邻接表实现

        (1).存储结构以及基本函数部分

/* ===预定义=== */
#define MAX_VEX_NUM 10
#define INF 2147483647

typedef int VertexType;            //顶点数据类型
typedef int EdgeType;               //边权值
bool visited[MAX_VEX_NUM];      //全局数组  负责BFS与DFS时的顶点访问标记
/* ===辅助队列=== */
//存储结构循环队列
typedef struct{
    int data[MAX_VEX_NUM];         //字符型
    int front;          //队头
    int rear;           //队尾
} SqQueue;
//初始化
void InitQueue(SqQueue &q){
    q.front = q.rear = 0;       //做法一 队头指向队首元素 队尾指向队尾元素下一位置 === 先入队再更新队尾  先出队再更细队头
    //q.front = q.rear = MAX_VEX_NUM - 1; //做法二 队头指向队首元素前一位置 队尾指向队尾元素 === 先更新队尾再入队 先更新队头再出队
}
//数据结构中增加元素个数计数器/数据结构中增加标识tag区分空满/牺牲一个存储位置
//判空一 队满条件为(q.rear+1)%MAX_VEX_NUM==q.front
bool QueueEmpty(SqQueue q){
    if(q.front==q.rear){
        return true;
    }else{
        return false;
    }
}
//入队
bool EnQueue(SqQueue &q,int x){
    if((q.rear+1)%MAX_VEX_NUM==q.front){        //队尾下一位置等于队头了 本方法牺牲一个存储单元
        return false;
    }
    q.data[q.rear] = x;
    q.rear = (q.rear + 1) % MAX_VEX_NUM;        //移动队列尾
    return true;
}
//出队
bool DeQueue(SqQueue &q,int &x){
    if(q.front==q.rear){
        return false;
    }
    x = q.data[q.front];
    q.front = (q.front + 1) % MAX_VEX_NUM;
    return true;
}
/* ===辅助队列=== */

/* ===辅助栈=== */
typedef struct{
    int data[MAX_VEX_NUM];
    int top;        //栈顶指针
} SqStack;
//初始化
void InitStack(SqStack &s){     //不加引用无法正确初始化!!!
    s.top = -1;     //栈顶指针指向当前元素,插入时先++再插入
}
//判断空,栈空返回1,不空返回0
bool StackEmpty(SqStack s){
    if(s.top==-1){
        return true;
    }else{
        return false;
    }
}
//入栈
bool Push(SqStack &s,int x){
    if(s.top==MAX_VEX_NUM-1){
        return false;
    }
    s.data[++s.top] = x;      //先加加
    return true;
}
//出栈
bool Pop(SqStack &s,int &x){
    if(s.top==-1){
        return false;
    }
    x = s.data[s.top--];      //先出栈再减一
    return true;
}
//取栈顶元素
bool GetTop(SqStack s,int &x){
    if(s.top==-1){
        return false;
    }
    x = s.data[s.top];
    return true;
}
/* ===辅助栈=== */

/*===邻接表结构===*/
//边表结点
typedef struct ArcNode{
    int adjv
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值