如题 自用笔记 如有错误欢迎及时指正
目录
一.算法描述
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