广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++实现Dijkstra算法的示例代码
  • 268
分享到

C++实现Dijkstra算法的示例代码

2024-04-02 19:04:59 268人浏览 安东尼
摘要

目录一、算法原理二、具体代码1.graph类2.PathFinder类3. main.cpp三、示例一、算法原理 链接: Dijkstra算法及其c++实现参考这篇文章 二、具体代码

一、算法原理

链接: Dijkstra算法及其c++实现参考这篇文章

二、具体代码

1.graph类

graph类用于邻接表建立和保存有向图。

graph.h:

#ifndef GRAPH_H
#define GRAPH_H

#include <iOStream>
#include <string>
#include <vector>
#include <stdlib.h>

using namespace std;

// 定义顶点
typedef struct Edgenode {
	int adjvex;	// 顶点下标
	struct  EdgeNode *next;	// 下一条边的指针
	double cost;	// 当前边的代价

	EdgeNode();
	~EdgeNode();
} EdgeNode;


// 定义顶点表
typedef struct VexList
{
	string Vexs;  //用来存储顶点信息
	EdgeNode *firstedge;  //用来存储当前顶点的下一个顶点

	VexList();
	~VexList();
} VertexList;



// 定义图
typedef class GraphList {
public:
	GraphList();
	~GraphList();

	void PrintGraph();	// 打印图
	void CreateGraph();	// 构建图

	vector<VexList> VexList;
	int Vertexs, Edges;

} GraphList;

typedef GraphList* GraphListPtr;


#endif

graph.cpp

#include <graph.h>

EdgeNode::EdgeNode() {
	cost = 0;
	next = nullptr;
}
EdgeNode::~EdgeNode() {
	//cout << "delete Node" << endl;
}

VexList::VexList() {
	firstedge = nullptr;
}
VexList::~VexList() {
	//cout << "delete VexList" << endl;
}

GraphList::GraphList() {
	VexList.clear();
}

GraphList::~GraphList() {
	//cout << "delete GraphList" << endl;
}

void GraphList::PrintGraph() {
	cout << "所建立的地图如以下所示:" << endl;
	for (int i = 0; i< Vertexs; i++) {
		cout << VexList[i].Vexs;             //先输出顶点信息
		EdgeNode * e = VexList[i].firstedge;
		while (e) {                           //然后就开始遍历输出每个边表所存储的邻接点的下标
			if (e->cost == -1) {
				cout << "---->" << e->adjvex;
			}
			else {
				cout << "-- " << e->cost << " -->" << e->adjvex;
			}
			e = e->next;
		}
		cout << endl;
	}
}

void GraphList::CreateGraph() {
	EdgeNode *e = new EdgeNode();
	cout << "请输入顶点数和边数:" << endl;
	cin >> Vertexs >> Edges;
	cout << "请输入顶点的信息:" << endl;

	for (int i = 0; i <Vertexs; ++i) {
		VertexList tmp;
		cin >> tmp.Vexs;
		tmp.firstedge = NULL;
		VexList.push_back(tmp);
	}

	for (int k = 0; k < Edges; ++k) {
		int i, j;	//(Vi,Vj)
		double cost;
		cout << "请输入边(Vi,Vj)与 cost:" << endl;
		cin >> i >> j >> cost;
		if (VexList[i].firstedge == NULL) {//当前顶点i后面没有顶点
			e = new EdgeNode;
			e->adjvex = j;
			e->cost = cost;
			e->next = NULL;
			VexList[i].firstedge = e;
		}
		else {  //当前i后面有顶点
			EdgeNode *p = VexList[i].firstedge;
			while (p->next) {
				p = p->next;
			}
			e = new EdgeNode;
			e->adjvex = j;
			e->cost = cost;
			e->next = NULL;
			p->next = e;
		}
	}
}

2.PathFinder类

PathFinder类用于搜索最短路径

pathFinder.h

#ifndef PATH_FINDER_H
#define PATH_FINDER_H

#include <iostream>
#include <graph.h>
#include <queue>

enum State{OPEN = 0, CLOSED, UNFIND};
// 定义dijkstra求解器
class DijNode {

public:
	DijNode();
	DijNode(double _val);
	~DijNode() {};
	double getCost() { return m_cost; }
	State getState() { return m_state; }
	void setCost(double _val) { m_cost = _val; }
	void setState(State _state) { m_state = _state; }
	int getIndex() { return m_index; }
	void setIndex(int _idx) { m_index = _idx; }
	void setPred(DijNode* _ptr) { preNode = _ptr; }
	DijNode* getPred() { return preNode; }

	VertexList Vertex;
private:
	int m_index;
	double m_cost;	// 起点到当前点的代价
	State m_state;
	DijNode* preNode;	// 保存父节点
};

typedef DijNode* DijNodePtr;

// 构造优先队列用的
struct cmp {
	bool operator() (DijNodePtr &a, DijNodePtr &b) {
		return a->getCost() > b->getCost();
	}
};

class PathFinder {
public:
	priority_queue<DijNodePtr, vector<DijNodePtr>, cmp > openList;//用优先队列做openList,队首元素为最小值
	vector<DijNodePtr> m_path;	// 存放最终路径
	PathFinder() {
		openList.empty();
		m_path.clear();
	}
	~PathFinder() {};

	void StoreGraph(GraphListPtr _graph);
	void Search(int start, int end);
	void retrievePath(DijNodePtr _ptr);

	vector<DijNodePtr> NodeList;

private:
	GraphListPtr m_graph;
	
};

typedef PathFinder* PathFinderPtr;
#endif

PathFinder.cpp

#include <PathFinder.h>

DijNode::DijNode() {
	m_cost = -1;	// -1表示未被探索过,距离为无穷,非负数表示已经被探索过
	m_index = -1;
	m_state = UNFIND;	// OPEN表示openlist, CLOSED表示在closeList中,UNFIND表示未探索过
	preNode = nullptr;
}

DijNode::DijNode(double _val) {
	m_cost = _val;	// -1表示未被探索过,非负数表示已经被探索过
	m_index = -1;
	m_state = UNFIND;	// OPEN表示openlist, CLOSED表示在closeList中,UNFIND表示未探索过
	preNode = nullptr;
}

void PathFinder::StoreGraph(GraphListPtr _graph) {
	for (int i = 0; i < _graph->VexList.size(); ++i) {
		DijNodePtr node = new DijNode();
		node->Vertex = _graph->VexList[i];
		node->setIndex(i);
		NodeList.push_back(node);
	}
}

void PathFinder::Search(int start, int end) {
	// 搜索起点
	DijNodePtr m_start = NodeList[start];
	m_start->setCost(0);
	m_start->setIndex(start);
	m_start->setState(OPEN);
	openList.push(m_start);

	int count = 0;
	while (!openList.empty()) {

		
		// 弹出openList中的队首元素
		DijNodePtr cur = openList.top();
		cur->setState(CLOSED);	// 加入closelist中
		openList.pop();

		// 遍历队首元素所有的边
		EdgeNode *e = cur->Vertex.firstedge;
		while (e != nullptr) {
			int _index = e->adjvex;
			double _cost = e->cost;
			
			//cout << "_cost = " << _cost << endl;
			// 如果节点在close list中,直接跳过
			if (NodeList[_index]->getState() == CLOSED) {
				continue;
			}

			if (NodeList[_index]->getCost() == -1) {
				NodeList[_index]->setCost(cur->getCost() + _cost);	// 更新代价
				NodeList[_index]->setPred(cur);		// 更新父节点
				NodeList[_index]->setState(OPEN);	// 加入open list中
				openList.push(NodeList[_index]);
			}
			else if (cur->getCost() + _cost < NodeList[_index]->getCost()) {
				// 如果从当前节点到第_index个节点的距离更短,更新距离和父节点
				NodeList[_index]->setCost(cur->getCost() + _cost);	// 更新代价
				NodeList[_index]->setPred(cur);		// 更新父节点
				NodeList[_index]->setState(OPEN);	// 加入open list中
			}

			e = e->next;
		}
	}

	cout << "最短距离为:" << NodeList[end]->getCost() << endl;
	retrievePath(NodeList[end]);

}

void PathFinder::retrievePath(DijNodePtr ptr) {
	while (ptr != nullptr) {
		m_path.push_back(ptr);
		ptr = ptr->getPred();
	}
	reverse(m_path.begin(),m_path.end());
}

3. main.cpp

主函数

#include <graph.h>
#include <PathFinder.h>


int main() {
	cout << "构建地图" << endl;
	GraphListPtr graph = new GraphList();
	graph->CreateGraph();

	cout << "\n \n";
	graph->PrintGraph();

	PathFinderPtr _solver = new PathFinder();
	_solver->StoreGraph(graph);

	cout << "\n \n";

	int start, end;
	cout << "输入起点" << endl;
	cin >> start;

	cout << "输入终点" << endl;
	cin >> end;

	cout << "\n \n";

	_solver->Search(start, end);
	cout << "最短路径为:";
	 
	for (int i = 0; i < _solver->m_path.size(); ++i) {
		 cout << _solver->m_path[i]->Vertex.Vexs ;
		 if (i < _solver->m_path.size() - 1)
			 cout << "-->";
	}
	cout << endl;

	system("pause");
	return 0;
}

三、示例

以上就是C++实现Dijkstra算法的示例代码的详细内容,更多关于C++ Dijkstra算法的资料请关注编程网其它相关文章!

--结束END--

本文标题: C++实现Dijkstra算法的示例代码

本文链接: https://www.lsjlt.com/news/164362.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++实现Dijkstra算法的示例代码
    目录一、算法原理二、具体代码1.graph类2.PathFinder类3. main.cpp三、示例一、算法原理 链接: Dijkstra算法及其C++实现参考这篇文章 二、具体代码...
    99+
    2022-11-13
  • Java实现Dijkstra算法的示例代码
    目录一 问题描述二 实现三 测试一 问题描述 小明为位置1,求他到其他各顶点的距离。 二 实现 package graph.dij...
    99+
    2022-11-13
  • C#实现抢红包算法的示例代码
    目录二倍均值法(公平版) 线段切割法(手速版) 二倍均值法(公平版)  发出一个固定金额的红包,由若干个人来抢,需要满足哪些规则? 1.所有人抢到金额之...
    99+
    2022-11-13
  • java实现最短路径算法之Dijkstra算法的示例
    这篇文章主要介绍了java实现最短路径算法之Dijkstra算法的示例,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、知识准备:1、表示图的数据结构用于存储图的数据结构有多...
    99+
    2023-05-31
    java dijkstra
  • C#实现常见加密算法的示例代码
    目录前言1. Base64编码1.1 原理介绍1.2 C#代码2. 凯撒密码2.1 原理介绍2.2 C#代码3. Vigenere密码3.1 原理介绍3.2 C#代码4. DES4....
    99+
    2022-11-13
  • 怎么使用C++实现Dijkstra算法
    本篇内容介绍了“怎么使用C++实现Dijkstra算法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!具体代码1.graph类graph类用于...
    99+
    2023-07-02
  • C++实现图的遍历算法(DFS,BFS)的示例代码
    目录图的定义图的相关术语图的创建(邻接矩阵)---结构体图的创建(邻接矩阵)---邻接矩阵的创建图的创建(邻接表)---结构体图的创建(邻接表)---邻接表的创建对邻接矩阵进行深度优...
    99+
    2022-11-13
  • Java实现Kruskal算法的示例代码
    目录介绍一、构建后的图二、代码三、测试介绍 构造最小生成树还有一种算法,即 Kruskal 算法:设图 G=(V,E)是无向连通带权图,V={1,2,...n};设最小生成树 T=(...
    99+
    2022-11-13
  • PHP实现LRU算法的示例代码
    本篇文章主要给大家介绍了PHP的相关知识,LRU是Least Recently Used 近期最少使用算法, 内存管理的一种页面置换算法,下面将详解LRU算法的原理以及实现,下面一起来看一下,希望对大家有帮助。(推荐教程:PHP视频教程)原...
    99+
    2022-08-08
    php
  • Java实现Floyd算法的示例代码
    目录一 问题描述二 代码三 实现一 问题描述 求节点0到节点2的最短路径。 二 代码 package graph.floyd; ...
    99+
    2022-11-13
  • C语言实现经典排序算法的示例代码
    目录一、冒泡排序1.原理2.实现3.算法分析二、选择排序1.原理2.实现3.算法分析三、插入排序1.原理2.实现3.算法分析四、希尔排序1.原理2.实现3.算法分析总结一、冒泡排序 ...
    99+
    2022-11-13
    C语言排序算法 C语言排序
  • C++实现RSA加密解密算法是示例代码
    目录一、什么是RSA算法1.对称加密2.非对称加密3.非对称加密的应用二、RSA算法的基础操作步骤1.生成公钥和私钥2.用公钥加密信息 3.用私钥解密信息三、AC代码四、R...
    99+
    2022-11-13
  • C语言线性代数算法实现矩阵示例代码
    目录C语言实现矩阵特殊矩阵特殊矩阵验证C语言实现矩阵 矩阵作为一个结构体而言,至少要包含行数、列数以及数据。 #include <stdio.h> #include ...
    99+
    2022-11-12
  • Dijkstra算法原理及C++怎么实现
    这篇文章主要介绍“Dijkstra算法原理及C++怎么实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Dijkstra算法原理及C++怎么实现”文章能帮助大家解决问题。什么是最短路径问题如果从图中...
    99+
    2023-07-02
  • C#实现一阶卡尔曼滤波算法的示例代码
    //FilterKalman.cs namespace FusionFiltering { public class FilterKalman { ...
    99+
    2022-11-12
  • C++实现双目立体匹配Census算法的示例代码
    上一篇介绍了双目立体匹配SAD算法,这一篇介绍Census算法。 Census原理: 在视图中选取任一点,以该点为中心划出一个例如3 × 3 的矩形,矩形中除中心点之外的...
    99+
    2022-11-13
    C++ 双目立体匹配 C++ Census算法 C++ 双目立体匹配 Census
  • C#实现FFT(递归法)的示例代码
    目录1. C#实现复数类2. 递归法实现FFT3. 补充:窗函数1. C#实现复数类 我们在进行信号分析的时候,难免会使用到复数。但是遗憾的是,C#没有自带的复数类,以下提供了一种复...
    99+
    2022-11-13
  • Java实现雪花算法的示例代码
    一、介绍 SnowFlow算法是Twitter推出的分布式id生成算法,主要核心思想就是利用64bit的long类型的数字作为全局的id。在分布式系统中经常应用到,并且,在id中加入...
    99+
    2022-11-13
  • Java实现抽奖算法的示例代码
    目录一、题目描述二、解题思路三、代码详解四、优化抽奖算法解题思路代码详解一、题目描述 题目: 小虚竹为了给粉丝送福利,决定在参与学习打卡活动的粉丝中抽一位幸运粉丝,送份小礼物。为了公...
    99+
    2022-11-13
  • C++实现MyString的示例代码
    MyString的构造、析构、拷贝构造、赋值运算 class String { char* str; public: String(const char* p = NULL) :...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作