数据结构与算法分析-C++描述 第9章 图论算法(单源最短路径问题之Dijkstra算法邻接表实现)

单源最短路径问题(Single Source Shortest Path Problem):

        给定一个加权图G = (V,E)和一个特定顶点s作为输入,找到从sG中每一个其他顶点的最短加权路径(如下图1示,求顶点1到顶点6的最短路径):即\min (Weight(Graph\ g,vertex\ s))

数据结构与算法分析-C++描述 第9章 图论算法(单源最短路径问题之Dijkstra算法邻接表实现)_第1张图片

                                                                                 图1 单源最短路径图示 

Dijkstra算法描述:

        解决单源最短路径的问题的一般方法为Dijkstra算法,这个有30年历史的解法是贪心算法(greedy algorithm)最好的例子。其算法思想为,首先把起点到所有点的距离存下来找个最短的,然后松弛一次再找出最短的。所谓的松弛操作就是,遍历一遍看通过刚刚找到的距离最短的点作为中转站会不会更近,如果更近了就更新距离,这样把所有的点找遍之后就存下了起点到其他所有点的最短距离。

Dijkstra行为描述:

        设起点为1号顶点,终点为6号顶点。标记1号顶点为visited,则邻接顶点为3, 5, 6。此时对应的距离dist数组与对应的visited数组见下图。(注黑色标注即为visited)。

数据结构与算法分析-C++描述 第9章 图论算法(单源最短路径问题之Dijkstra算法邻接表实现)_第2张图片

  从dist数组中寻找下一个最小距离为10(顶点3)时对应的图示和dist数组见下图。此时更新4号顶点(20 < inf)。

数据结构与算法分析-C++描述 第9章 图论算法(单源最短路径问题之Dijkstra算法邻接表实现)_第3张图片

从dist数组中寻找下一个最小距离为20(顶点4)时对应的图示和dist数组见下图。此时更新6号顶点(45 < 60)。 

数据结构与算法分析-C++描述 第9章 图论算法(单源最短路径问题之Dijkstra算法邻接表实现)_第4张图片

从dist数组中寻找下一个最小距离为30(顶点5)时对应的图示和dist数组见下图。因为45 < (30 + 20),此时不更新6号顶点。

数据结构与算法分析-C++描述 第9章 图论算法(单源最短路径问题之Dijkstra算法邻接表实现)_第5张图片

从dist数组中寻找下一个最小距离为45(顶点6)时对应的图示和dist数组见下图。

数据结构与算法分析-C++描述 第9章 图论算法(单源最短路径问题之Dijkstra算法邻接表实现)_第6张图片

最后是2号顶点的访问。

数据结构与算法分析-C++描述 第9章 图论算法(单源最短路径问题之Dijkstra算法邻接表实现)_第7张图片

 最终将得到从顶点1到其他顶点的最短距离的数组dist。对于顶点1到其他任意顶点的最短距离均在访问过程中被更新。

Dijkstra算法应用:

        在诸如航空路线、大型交通运输等求解最短路径问题方面,Dijstra算法具有广泛应用。

Dijkstra实例:使用邻接表实现Dijstra算法,打印邻接表信息,求解起点和终点的最短路径。

//main.cpp
#include
#include
#include
#include
#include

using namespace std;

const int MAX_NUM = 20;
const int INF = 9999;

//define the Node type queue
struct Node{
	int id;
	int w;
	
	//overload operator< since the defalut is max heap for priority_queue
	friend bool operator<(Node n1, Node n2){
		return (n1.w > n2.w);
	}
};

//define the dist vector to update the distance
vector dist(MAX_NUM);

//EdageNode contains adjointVertex, weight and next pointer
struct EdageNode{
	int adjointVertex;
	int weight;
	EdageNode *next;
	
	//EdageNode constructor
	EdageNode(int a = 0, int w = 0, EdageNode *n = NULL):adjointVertex(a), weight(w), next(n){
	
	};
};

//AdjointList contains data and firstEdage pointer
struct AdjointList{
	int data;
	EdageNode *firstEdage;
};

//Graph contains numVertex, numEdge and the AdjointList type vector adjointList
struct Graph{
	int numVertex;
	int numEdge;
	vector adjointList;
	
	//Graph constructor
	Graph(int n = 10):adjointList(n){
	};
};

//createGraph with numEdge and numVertex
void createGraph(Graph &g, int numEdge, int numVertex);

//Dijkstra algorithm
void Dijkstra(Graph g, int start);

int main(){
	int numEdge, numVertex;
	cout << "Enter the number of Edage and vertex splited with space : ";
	cin >> numEdge >> numVertex;
	Graph g;
	createGraph(g, numEdge, numVertex);
	cout << "The adjointList info as follow " << endl;
	for(int i = 1; i <= numEdge; i++)
	{
		EdageNode *node = g.adjointList[i].firstEdage;
		cout << i;
		while(node)
		{
			cout << " -> " << node->adjointVertex;
			node = node->next;
		}
		cout << endl;
	}
	int start, end;
	cout << "Enter the start and end vertex to pass : ";
	cin >> start >> end;
	Dijkstra(g, start);
	if(dist[end].w != INF){
		cout << " the minimum distance between " << start << " and " << end << " is " << dist[end].w << endl;
	}else{
		cout << " the path dose not exist ! " << endl;
	}
	return 0;
}

void createGraph(Graph &g, int numEdge, int numVertex){
	g.numEdge = numEdge;
	g.numVertex = numVertex;
	//create EdageNode
	for(int i = 0 ; i < g.numVertex; i++){
		g.adjointList[i].firstEdage = NULL;
	}
	cout << "E(v_i, v_j, w) means v_i -> v_j with weight w " << endl;
	int v_i, v_j, w;
	EdageNode *node;
	//create adjointList
	for(int i = 0; i < g.numVertex; i++){
		cout << "Enter E(V_i, v_j, w) : ";
		cin >> v_i >> v_j >> w;
		node = new EdageNode(v_j, w, g.adjointList[v_i].firstEdage);
		g.adjointList[v_i].firstEdage = node;
	}
}

void Dijkstra(Graph g, int start){
	vector visited(g.numVertex);			//mark the visited vertex
	priority_queue dijQueue;				//priority_queue container
	for(int i = 0; i < g.numVertex; i++){		//initialize the array
		dist[i].id = i;
		dist[i].w = INF;
		visited[i] = false;
	}
	dist[start].w = 0;							//update currernt vertex weight
	dijQueue.push(dist[start]);
	EdageNode *node;
	while(!dijQueue.empty()){
		Node temp = dijQueue.top();
		dijQueue.pop();
		int u = temp.id;
		if(visited[u]){
			continue;
		}
		visited[u] = true;						//update currernt vertex visited statue
		node = g.adjointList[u].firstEdage;		//get the firstEdage of currernt vertex
		while(node){
			if( (!visited[node -> adjointVertex]) && (dist[node -> adjointVertex].w > dist[u].w + node -> weight) ){	//find the minimum distance
				dist[node -> adjointVertex].w = dist[u].w + node -> weight;
				dijQueue.push(dist[node -> adjointVertex]);
			}
			node = node -> next;				//get the next Edage of currernt vertex
		}
	}
}

实验结果:

数据结构与算法分析-C++描述 第9章 图论算法(单源最短路径问题之Dijkstra算法邻接表实现)_第8张图片

practice makes perfect ! 

你可能感兴趣的:(C++,数据结构与算法分析-C++描述)