C++ 如何初始化图中两个节点之间的权重?
我正在研究Dijkstra的最短路径算法。在add_边函数上初始化图的两个节点之间的权重时遇到问题。正因为如此,我在处理dijkstra函数时遇到了问题。而且我不允许使用向量。 以下是我目前获得的代码:C++ 如何初始化图中两个节点之间的权重?,c++,graph,dijkstra,C++,Graph,Dijkstra,我正在研究Dijkstra的最短路径算法。在add_边函数上初始化图的两个节点之间的权重时遇到问题。正因为如此,我在处理dijkstra函数时遇到了问题。而且我不允许使用向量。 以下是我目前获得的代码: #include <iostream> #include <limits.h> using namespace std; class ListNode; class Node { public: int visited, distance; char
#include <iostream>
#include <limits.h>
using namespace std;
class ListNode;
class Node {
public:
int visited, distance;
char label;
Node* prev;
Node* next;
ListNode* adjacent;
//node constructor
Node(char label) {
this->label = label;
this->visited = 0;
this->distance=0;
this->next = 0;
this->prev = 0;
this->adjacent = 0;
}
};
class ListNode {
public:
Node * datum;
int weight;
ListNode* next;
ListNode* prev;
//Listnode constructor
ListNode(Node* datum) {
this->datum = datum;
this->prev = 0;
this->next = 0;
this->weight=0;
}
};
class Graph {
public:
Node * vertices;
Node* visited;
ListNode* head;
ListNode* tail;
//Graph constructor
Graph() {
this->head = 0;
this->tail = 0;
this->vertices = 0;
this->visited = 0;
}
//adjaceny list destructor_helper
void destructorAdjacent_helper(ListNode* ln) {
if (ln == 0)
return;
else {
destructorAdjacent_helper(ln->next);
delete ln;
}
}
//node destructor_helper
void destructorNodes_helper(Node* temp) {
if (temp == 0)
return;
else {
destructorNodes_helper(temp->next);
destructorAdjacent_helper(temp->adjacent);
delete temp;
}
}
//Graph destructor
~Graph() {
destructorNodes_helper(this->vertices);
}
//add node to the graph
int add_node(char label) {
//every label must be unique
for (Node* temp = this->vertices; temp != 0; temp = temp->next) {
if (temp->label == label)
return 0;
}
//after uniqueness test add node to the graph
Node* newNode = new Node(label);
if (this->vertices != 0) {
this->vertices->prev = newNode;
}
newNode->next = this->vertices;
this->vertices = newNode;
return 1;
}
//add edge from and to the given nodes
int add_edge(char from, char to, int weight) {
Node *temp, *start, *end;
//check the start node
for (temp = this->vertices; temp != 0; temp = temp->next) {
if (temp->label == from)
break; //goes out of the loop after start node is found
}
if (temp == 0)
return 0;
else
start = temp;
//check the end node
for (temp = this->vertices; temp != 0; temp = temp->next) {
if (temp->label == to)
break; //breaks from the loop after end node is found
}
if (temp == 0)
return 0;
else
end = temp;
ListNode* endNode = new ListNode(end);
if (start->adjacent != 0) {
start->adjacent->prev = endNode;
}
endNode->next = start->adjacent;
start->adjacent = endNode;
//????????????
//how do we insert the weight between from and to nodes ???
return 1;
}
//push a node to the stack or queue as necessary
void push(Node* node) {
ListNode* newNode = new ListNode(node);
if (this->head == 0) {
this->head = newNode;
this->tail = newNode;
}
else {
this->head->prev = newNode;
newNode->next = this->head;
this->head = newNode;
}
}
//pops the tail node from the queue
Node* queue_pop() {
if (this->head == 0) {
return 0;
}
else {
Node* retVal = this->tail->datum;
ListNode* temp = this->tail;
this->tail = this->tail->prev;
if (this->tail != 0) {
this->tail->next = 0;
}
else {
this->head = 0;
}
delete temp;
return retVal;
}
}
void visit(Node* node) {
//remove from vertices list
if (node->prev != 0) {
node->prev->next = node->next;
}
if (node->next != 0) {
node->next->prev = node->prev;
}
if (this->vertices == node) {
this->vertices = node->next;
}
//add to visited list
if (this->visited != 0) {
this->visited->prev = node;
}
node->next = this->visited;
node->prev = 0;
this->visited = node;
//mark as visited
node->visited = 1;
}
void dijkstra(char src){
Node*temp = this->vertices;
ListNode* LTemp;
for(;temp!=0; temp=temp->next){
temp->distance = INT_MAX;
temp->visited=0;
}
src->distance=0;
push(src);
while(this->head!=0){
temp=queue_pop();
if (!temp->visited) {
//mark as visited
visit(temp);
for (LTemp = temp->adjacent; LTemp != 0; LTemp = LTemp->next) {
if (!LTemp->datum->visited) {
push(LTemp->datum);
}
}
}
//push top of vertices if queue is empty and vertices is not
if (!this->head && this->vertices) {
push(this->vertices);
}
//algorithm to follow:
for each neighbor u of v:
//not sure how to get length(v,u)???
alt := dist[v] + length(v, u)
if alt < dist[u]:
dist[u] := alt
}
}
};
int main(){
//create a new graph
Graph* G = new Graph();
//add nodes to the graph
G->add_node('A');
G->add_node('B');
G->add_node('C');
G->add_node('D');
G->add_node('E');
G->add_node('F');
//add edges to the nodes
G->add_edge('C', 'B', 3);
G->add_edge('C', 'E', 5);
G->add_edge('C', 'D', 6);
G->add_edge('E', 'C', 5);
G->add_edge('E', 'D', 2);
G->add_edge('D', 'C', 6);
G->add_edge('D', 'E', 2);
G->add_edge('B', 'C', 3);
G->add_edge('B', 'A', 7);
G->add_edge('A', 'B', 7);
G->add_edge('B', 'D', 4);
G->add_edge('D', 'B', 4);
G->add_edge('E', 'F', 1);
G->add_edge('F', 'E', 1);
G->dijkstra('C');
//free the dynamically allocated memory
delete G;
return 0;
}
#包括
#包括
使用名称空间std;
类ListNode;
类节点{
公众:
int,距离;
字符标签;
节点*prev;
节点*下一步;
ListNode*相邻;
//节点构造函数
节点(字符标签){
此->标签=标签;
此->已访问=0;
这个->距离=0;
本->下一步=0;
此->上一个=0;
该->相邻=0;
}
};
类ListNode{
公众:
节点*基准;
整数权重;
ListNode*下一步;
ListNode*prev;
//Listnode构造函数
ListNode(节点*基准){
这个->基准=基准;
此->上一个=0;
本->下一步=0;
这个->权重=0;
}
};
类图{
公众:
节点*顶点;
节点*已访问;
ListNode*头;
ListNode*尾部;
//图构造函数
图(){
这个->头=0;
这->尾=0;
这个->顶点=0;
此->已访问=0;
}
//邻接列表析构函数
void destructorAdjacent\u辅助对象(ListNode*ln){
如果(ln==0)
返回;
否则{
析构函数邻接辅助程序(ln->next);
删除项次;
}
}
//节点析构函数
void destructorNodes_辅助对象(节点*temp){
如果(温度==0)
返回;
否则{
析构函数节点(临时->下一步);
析构函数邻接辅助对象(临时->邻接);
删除临时文件;
}
}
//图析构函数
~Graph(){
destructorNodes_辅助对象(此->顶点);
}
//将节点添加到图形中
int add_节点(字符标签){
//每个标签都必须是唯一的
对于(节点*temp=this->顶点;temp!=0;temp=temp->next){
如果(临时->标签==标签)
返回0;
}
//唯一性测试后,将节点添加到图中
节点*newNode=新节点(标签);
如果(此->顶点!=0){
此->顶点->上一个=新节点;
}
新建节点->下一步=此->顶点;
此->顶点=新节点;
返回1;
}
//从和向给定节点添加边
int add_边(char-from、char-to、int-weight){
节点*温度,*开始,*结束;
//检查开始节点
对于(临时=此->顶点;临时!=0;临时=临时->下一步){
如果(临时->标签==来自)
break;//在找到开始节点后退出循环
}
如果(温度==0)
返回0;
其他的
启动=温度;
//检查结束节点
对于(临时=此->顶点;临时!=0;临时=临时->下一步){
如果(临时->标签==to)
break;//在找到结束节点后从循环中断
}
如果(温度==0)
返回0;
其他的
结束=温度;
ListNode*endNode=新ListNode(结束);
如果(开始->相邻!=0){
开始->相邻->上一个=结束节点;
}
结束节点->下一步=开始->相邻;
开始->相邻=结束节点;
//????????????
//如何在“从”和“到”节点之间插入权重???
返回1;
}
//根据需要将节点推送到堆栈或队列
无效推送(节点*节点){
ListNode*newNode=新ListNode(节点);
如果(此->头==0){
此->头部=新节点;
此->尾=新节点;
}
否则{
此->头部->上一个=新节点;
新建节点->下一步=此->头部;
此->头部=新节点;
}
}
//从队列中弹出尾部节点
节点*队列_pop(){
如果(此->头==0){
返回0;
}
否则{
节点*retVal=this->tail->datum;
ListNode*temp=此->尾部;
this->tail=this->tail->prev;
如果(此->尾部!=0){
本->尾->下一步=0;
}
否则{
这个->头=0;
}
删除临时文件;
返回返回;
}
}
无效访问(节点*节点){
//从顶点列表中删除
如果(节点->上一个!=0){
节点->上一个->下一个=节点->下一个;
}
如果(节点->下一步!=0){
节点->下一步->上一步=节点->上一步;
}
如果(此->顶点==节点){
此->顶点=节点->下一步;
}
//添加到已访问列表
如果(此->已访问!=0){
此->已访问->上一个=节点;
}
节点->下一步=此->已访问;
节点->上一个=0;
此->已访问=节点;
//标记为已访问
节点->访问次数=1;
}
void dijkstra(char src){
节点*temp=此->顶点;
ListNode*LTemp;
对于(;temp!=0;temp=temp->next){
温度->距离=内部最大值;
温度->访问量=0;
}
src->distance=0;
推(src);
而(此->头部!=0){
temp=queue_pop();
如果(!temp->已访问){
//标记为已访问
访问(临时);
用于(LTemp=temp->next;LTemp!=0;LTemp=LTemp->next){
如果(!LTemp->数据->访问){
推送(LTemp->基准);
}
}
}
//如果队列为空而顶点不为空,则推送顶点的顶部
如果(!this->head&&this->顶点){
推(此->顶点);
}
//要遵循的算法:
对于v的每个相邻u:
//不确定如何获得长度(v,u)???
高度:=距离[v]+长度(v,u)
如果alt