亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++實(shí)現(xiàn)Dijkstra算法的示例代碼

 更新時(shí)間:2022年07月15日 16:50:06   作者:Hornswoggle  
迪杰斯特拉算法(Dijkstra)是由荷蘭計(jì)算機(jī)科學(xué)家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法。是從一個(gè)頂點(diǎn)到其余各頂點(diǎn)的最短路徑算法。本文將用C++實(shí)現(xiàn)Dijkstra算法,需要的可以參考一下

一、算法原理

鏈接: Dijkstra算法及其C++實(shí)現(xiàn)參考這篇文章

二、具體代碼

1.graph類(lèi)

graph類(lèi)用于鄰接表建立和保存有向圖。

graph.h:

#ifndef GRAPH_H
#define GRAPH_H

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

using namespace std;

// 定義頂點(diǎn)
typedef struct EdgeNode {
	int adjvex;	// 頂點(diǎn)下標(biāo)
	struct  EdgeNode *next;	// 下一條邊的指針
	double cost;	// 當(dāng)前邊的代價(jià)

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


// 定義頂點(diǎn)表
typedef struct VexList
{
	string Vexs;  //用來(lái)存儲(chǔ)頂點(diǎn)信息
	EdgeNode *firstedge;  //用來(lái)存儲(chǔ)當(dāng)前頂點(diǎn)的下一個(gè)頂點(diǎn)

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



// 定義圖
typedef class GraphList {
public:
	GraphList();
	~GraphList();

	void PrintGraph();	// 打印圖
	void CreateGraph();	// 構(gòu)建圖

	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;             //先輸出頂點(diǎn)信息
		EdgeNode * e = VexList[i].firstedge;
		while (e) {                           //然后就開(kāi)始遍歷輸出每個(gè)邊表所存儲(chǔ)的鄰接點(diǎn)的下標(biāo)
			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 << "請(qǐng)輸入頂點(diǎn)數(shù)和邊數(shù):" << endl;
	cin >> Vertexs >> Edges;
	cout << "請(qǐng)輸入頂點(diǎn)的信息:" << 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 << "請(qǐng)輸入邊(Vi,Vj)與 cost:" << endl;
		cin >> i >> j >> cost;
		if (VexList[i].firstedge == NULL) {//當(dāng)前頂點(diǎn)i后面沒(méi)有頂點(diǎn)
			e = new EdgeNode;
			e->adjvex = j;
			e->cost = cost;
			e->next = NULL;
			VexList[i].firstedge = e;
		}
		else {  //當(dāng)前i后面有頂點(diǎn)
			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類(lèi)

PathFinder類(lèi)用于搜索最短路徑

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;	// 起點(diǎn)到當(dāng)前點(diǎn)的代價(jià)
	State m_state;
	DijNode* preNode;	// 保存父節(jié)點(diǎn)
};

typedef DijNode* DijNodePtr;

// 構(gòu)造優(yōu)先隊(duì)列用的
struct cmp {
	bool operator() (DijNodePtr &a, DijNodePtr &b) {
		return a->getCost() > b->getCost();
	}
};

class PathFinder {
public:
	priority_queue<DijNodePtr, vector<DijNodePtr>, cmp > openList;//用優(yōu)先隊(duì)列做openList,隊(duì)首元素為最小值
	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;
	/*vector<DijNodePtr> NodeList;*/
};

typedef PathFinder* PathFinderPtr;
#endif

PathFinder.cpp

#include <PathFinder.h>

DijNode::DijNode() {
	m_cost = -1;	// -1表示未被探索過(guò),距離為無(wú)窮,非負(fù)數(shù)表示已經(jīng)被探索過(guò)
	m_index = -1;
	m_state = UNFIND;	// OPEN表示openlist, CLOSED表示在closeList中,UNFIND表示未探索過(guò)
	preNode = nullptr;
}

DijNode::DijNode(double _val) {
	m_cost = _val;	// -1表示未被探索過(guò),非負(fù)數(shù)表示已經(jīng)被探索過(guò)
	m_index = -1;
	m_state = UNFIND;	// OPEN表示openlist, CLOSED表示在closeList中,UNFIND表示未探索過(guò)
	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) {
	// 搜索起點(diǎn)
	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中的隊(duì)首元素
		DijNodePtr cur = openList.top();
		cur->setState(CLOSED);	// 加入closelist中
		openList.pop();

		// 遍歷隊(duì)首元素所有的邊
		EdgeNode *e = cur->Vertex.firstedge;
		while (e != nullptr) {
			int _index = e->adjvex;
			double _cost = e->cost;
			
			//cout << "_cost = " << _cost << endl;
			// 如果節(jié)點(diǎn)在close list中,直接跳過(guò)
			if (NodeList[_index]->getState() == CLOSED) {
				continue;
			}

			if (NodeList[_index]->getCost() == -1) {
				NodeList[_index]->setCost(cur->getCost() + _cost);	// 更新代價(jià)
				NodeList[_index]->setPred(cur);		// 更新父節(jié)點(diǎn)
				NodeList[_index]->setState(OPEN);	// 加入open list中
				openList.push(NodeList[_index]);
			}
			else if (cur->getCost() + _cost < NodeList[_index]->getCost()) {
				// 如果從當(dāng)前節(jié)點(diǎn)到第_index個(gè)節(jié)點(diǎn)的距離更短,更新距離和父節(jié)點(diǎn)
				NodeList[_index]->setCost(cur->getCost() + _cost);	// 更新代價(jià)
				NodeList[_index]->setPred(cur);		// 更新父節(jié)點(diǎn)
				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

主函數(shù)

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


int main() {
	cout << "構(gòu)建地圖" << 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 << "輸入起點(diǎn)" << endl;
	cin >> start;

	cout << "輸入終點(diǎn)" << 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++實(shí)現(xiàn)Dijkstra算法的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于C++ Dijkstra算法的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 可能是你看過(guò)最全的十大排序算法詳解(完整版代碼)

    可能是你看過(guò)最全的十大排序算法詳解(完整版代碼)

    排序算法是程序中常用的算法,下面這篇文章主要給大家介紹了關(guān)于十大排序算法的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • C語(yǔ)言實(shí)現(xiàn)頁(yè)面置換算法(FIFO、LRU)

    C語(yǔ)言實(shí)現(xiàn)頁(yè)面置換算法(FIFO、LRU)

    這篇文章主要介紹了通過(guò)C語(yǔ)言實(shí)現(xiàn)的兩種頁(yè)面置換算法:先進(jìn)先出(FIFO)頁(yè)面置換算法和最近最久未使用(LRU)頁(yè)面置換算法。文中的代碼具有一定的學(xué)習(xí)或工作價(jià)值,快來(lái)跟隨小編學(xué)習(xí)一下吧
    2021-12-12
  • C++實(shí)現(xiàn)猜數(shù)字游戲

    C++實(shí)現(xiàn)猜數(shù)字游戲

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)猜數(shù)字游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • Visual Studio 2022最新版安裝教程(圖文詳解)

    Visual Studio 2022最新版安裝教程(圖文詳解)

    本文主要介紹了Visual Studio 2022最新版安裝教程,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • C++遍歷文件夾目錄的方法

    C++遍歷文件夾目錄的方法

    這篇文章主要介紹了C++遍歷文件夾目錄的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • Visual?Studio2022報(bào)錯(cuò)無(wú)法打開(kāi)源文件?"openssl/conf.h"解決方法

    Visual?Studio2022報(bào)錯(cuò)無(wú)法打開(kāi)源文件?"openssl/conf.h"解決方法

    這篇文章主要介紹了Visual?Studio2022報(bào)錯(cuò)無(wú)法打開(kāi)源文件"openssl/conf.h"解決方式,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • C++實(shí)現(xiàn)LeetCode(86.劃分鏈表)

    C++實(shí)現(xiàn)LeetCode(86.劃分鏈表)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(86.劃分鏈表),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++?高精度乘法運(yùn)算的實(shí)現(xiàn)

    C++?高精度乘法運(yùn)算的實(shí)現(xiàn)

    本文主要介紹了C++?高精度乘法運(yùn)算的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • 詳解C++之類(lèi)和對(duì)象(1)

    詳解C++之類(lèi)和對(duì)象(1)

    類(lèi)是創(chuàng)建對(duì)象的模板,一個(gè)類(lèi)可以創(chuàng)建多個(gè)對(duì)象,每個(gè)對(duì)象都是類(lèi)類(lèi)型的一個(gè)變量;創(chuàng)建對(duì)象的過(guò)程也叫類(lèi)的實(shí)例化。每個(gè)對(duì)象都是類(lèi)的一個(gè)具體實(shí)例(Instance),擁有類(lèi)的成員變量和成員函數(shù)
    2021-11-11
  • C++學(xué)習(xí)小結(jié)之語(yǔ)句

    C++學(xué)習(xí)小結(jié)之語(yǔ)句

    本文給大家匯總介紹了下C++中比較基礎(chǔ)的知識(shí)--語(yǔ)句,常用的語(yǔ)句都有詳細(xì)介紹和附上了相關(guān)示例,十分實(shí)用,有需要的小伙伴可以參考下
    2015-07-07

最新評(píng)論