#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include <algorithm>
using namespace::std;
class Node;
class Edge
{
public:
Edge(Node* start, Node* end, int _cost = 0):from(start),to(end),cost(_cost)
{}
Node * getFromNode()
{
return from;
}
Node * getToNode()
{
return to;
}
int getCost()
{
return cost;
}
private:
Node * from;
Node * to;
int cost;
};
class Node
{
public:
Node(string name):pre(0),post(0),nodeName(name),visit(0),dist(INT_MAX)
{}
~Node()
{
for(int i = 0; i < adjList.size(); i++)
{
delete adjList[i];
}
adjList.clear();
}
void showList()
{
cout<<nodeName<<": ";
for(int i = 0; i < adjList.size(); i++)
{
cout<<adjList[i]->getToNode()->getName()<<" ";
}
cout<<endl;
}
void addAnode(Node* newNode, int cost)
{
Edge *newEdge = new Edge(this, newNode, cost);
adjList.push_back(newEdge);
}
void deleteAnode(string name)
{
for(int i = 0; i < adjList.size(); i++)
{
if(name == adjList[i]->getToNode()->getName())
{
delete adjList[i];
adjList.erase(adjList.begin() + i);
}
}
}
string getName()
{
return nodeName;
}
int getPre()
{
return pre;
}
void setPre(int _pre)
{
pre = _pre;
}
int getPost()
{
return post;
}
void setPost(int _post)
{
post = _post;
}
bool getStatus()
{
return visit;
}
void setStatus(bool _visit)
{
visit = _visit;
}
void setDist(int _dist)
{
dist = _dist;
}
int getDist()
{
return dist;
}
vector<Edge*>& getAdjList()
{
return adjList;
}
private:
string nodeName;
vector<Edge*> adjList;
int pre;
int post;
bool visit;
int dist;
};
class Graph
{
public:
Graph():clock(1)
{
}
Graph(Graph * inputGraph)
{
for(int i = 0; i < inputGraph->getList().size(); i++)
{
Node* node = new Node(inputGraph->getList()[i]->getName());
nodeList.push_back(node);
}
clock = 1;
}
~Graph()
{
for(int i = 0; i < nodeList.size(); i++)
{
delete nodeList[i];
}
nodeList.clear();
}
void resetClock()
{
clock = 0;
}
void clearVisit()
{
for(int i = 0; i < nodeList.size(); i++)
{
nodeList[i]->setStatus(0);
}
}
Node* searchNodeByName(string name)
{
for(int i = 0; i < nodeList.size(); i++)
{
if(nodeList[i]->getName() == name)
return nodeList[i];
}
}
void addNode(Node * node)
{
nodeList.push_back(node);
}
void deleteNode(string name)
{
Node * tmp = getNodeByName(name);
int pos;
for(int i = 0; i < nodeList.size(); i++)
{
nodeList[i]->deleteAnode(name);
if(nodeList[i]->getName() == name)
{
pos = i;
}
}
nodeList[pos]->getAdjList().clear();
delete nodeList[pos];
nodeList.erase(nodeList.begin() + pos);
}
void display()
{
for(int i = 0; i < nodeList.size(); i++)
{
//cout<<nodeList[i]->getPre()<<" "<<nodeList[i]->getPost()<<" ";
cout<<nodeList[i]->getDist()<<" ";
nodeList[i]->showList();
}
}
vector<Node* > & getList()
{
return nodeList;
}
Node* getNodeByName(string name)
{
for(int i = 0; i < nodeList.size(); i++)
{
if(nodeList[i]->getName() == name)
return nodeList[i];
}
}
void DFS()
{
for(int i = 0; i < nodeList.size(); i++)
{
if(nodeList[i]->getStatus() == 0)
{
explore(nodeList[i]);
}
}
}
void BFS()
{
queue<Node*> bfsQ;
Node* tmp;
bfsQ.push(nodeList[0]);
nodeList[0]->setDist(0);
while(bfsQ.size() != 0)
{
tmp = bfsQ.front();
bfsQ.pop();
for(int i = 0; i < tmp->getAdjList().size(); i++)
{
if(tmp->getAdjList()[i]->getToNode()->getDist() == INT_MAX)
{
tmp->getAdjList()[i]->getToNode()->setDist(tmp->getDist() + 1);
bfsQ.push(tmp->getAdjList()[i]->getToNode());
}
}
}
}
void Dijkstra()
{
vector<Node *> queue(nodeList);
nodeList[0]->setDist(0);
//queue.push_back(nodeList[0]);
while(queue.size() != 0)
{
sort//可以用lambda表达式, 定义匿名函数, 语法是 [] (参数表){ 实现 } 匿名函数会自动成为友元
(queue.begin(), queue.end(), [](Node* node1, Node* node2)
{
return(node1->getDist() < node2->getDist());
}
);
Node* tmp = queue.front();
queue.erase(queue.begin());
cout<<queue.size()<<endl;
for(int i = 0; i < tmp->getAdjList().size(); i++)
{
if(tmp->getAdjList()[i]->getToNode()->getDist() > tmp->getAdjList()[i]->getCost() + tmp->getDist())
tmp->getAdjList()[i]->getToNode()->setDist(tmp->getAdjList()[i]->getCost() + tmp->getDist());
//queue.push_back(tmp->getAdjList()[i]->getToNode());
}
}
}
void Bellman()
{
nodeList[0]->setDist(0);
for(int j = 0; j < nodeList.size() - 1; j++)//bellman ford 算法关键点
{
//tmp = bellQ.front();
for(int x = 0; x < nodeList.size(); x++)
{
for(int i = 0; i < nodeList[x]->getAdjList().size(); i++)
{
if(nodeList[x]->getAdjList()[i]->getToNode()->getDist() > nodeList[x]->getAdjList()[i]->getCost() + nodeList[x]->getDist())
nodeList[x]->getAdjList()[i]->getToNode()->setDist(nodeList[x]->getAdjList()[i]->getCost() + nodeList[x]->getDist());
}
}
}
}
Graph* revese()
{
Graph* newGraph = new Graph(this);
for(int i = 0; i < nodeList.size(); i++)
{
for(int j = 0; j < nodeList[i]->getAdjList().size(); j++)
{
newGraph->getNodeByName(nodeList[i]->getAdjList()[j]->getToNode()->getName())->addAnode(newGraph->getNodeByName(nodeList[i]->getName()),0);
}
}
return newGraph;
}
void strong_component()
{
Graph * reverse_graph = new Graph;
reverse_graph = this->revese();
reverse_graph->DFS();
for(int i = 0; i < reverse_graph->getList().size() - 1; i++)
{
for(int j = i + 1; j < reverse_graph->getList().size(); j++)
{
if(reverse_graph->getList()[i]->getPost() > reverse_graph->getList()[j]->getPost())
{
Node * tmp;
tmp = reverse_graph->getList()[i];
reverse_graph->getList()[i] = reverse_graph->getList()[j];
reverse_graph->getList()[j] = tmp;
}
}
}
while(reverse_graph->getList().size() > 0)
{
this->explore(getNodeByName(reverse_graph->getList().back()->getName()));
//reverse_graph->getList().pop_back();
for(int i = 0; i < nodeList.size(); i++)
{
if(nodeList[i]->getStatus() == 1)
{
cout<<nodeList[i]->getName()<<" ";
//reverse_graph->display();
reverse_graph->deleteNode(nodeList[i]->getName());
this->deleteNode(nodeList[i]->getName());
i--;
}
}
cout<<endl;
this->clearVisit();
}
delete reverse_graph;
}
private:
vector<Node* > nodeList;
int clock;
void explore(Node* node)
{
node->setStatus(1);
node->setPre(clock);
clock++;
vector<Edge*> adjList = node->getAdjList();
for(int i = 0; i < adjList.size(); i++)
{
if(adjList[i]->getToNode()->getStatus() == 0)
{
explore(adjList[i]->getToNode());
}
}
node->setPost(clock);
clock++;
}
};
Graph* createGraph()
{
/* Strongly connected components algorithm
Node* node_A = new Node("A");
Node* node_B = new Node("B");
Node* node_C = new Node("C");
Node* node_D = new Node("D");
Node* node_E = new Node("E");
Node* node_F = new Node("F");
Node* node_G = new Node("G");
Node* node_H = new Node("H");
Node* node_I = new Node("I");
Node* node_J = new Node("J");
Node* node_K = new Node("K");
Node* node_L = new Node("L");
node_B->addAnode(node_A, 0);
node_B->addAnode(node_E, 0);
node_C->addAnode(node_B, 0);
node_C->addAnode(node_F, 0);
node_D->addAnode(node_B, 0);
node_E->addAnode(node_B, 0);
node_F->addAnode(node_C, 0);
node_F->addAnode(node_E, 0);
node_H->addAnode(node_F, 0);
node_H->addAnode(node_G, 0);
node_G->addAnode(node_E, 0);
node_G->addAnode(node_I, 0);
node_I->addAnode(node_J, 0);
node_J->addAnode(node_G, 0);
node_J->addAnode(node_L, 0);
node_K->addAnode(node_H, 0);
node_L->addAnode(node_K, 0);
Graph* graph = new Graph();
graph->addNode(node_A);
graph->addNode(node_B);
graph->addNode(node_C);
graph->addNode(node_D);
graph->addNode(node_E);
graph->addNode(node_F);
graph->addNode(node_G);
graph->addNode(node_H);
graph->addNode(node_I);
graph->addNode(node_J);
graph->addNode(node_K);
graph->addNode(node_L);
return graph;
*/
Node* node_A = new Node("A");
Node* node_B = new Node("B");
Node* node_C = new Node("C");
Node* node_D = new Node("D");
Node* node_E = new Node("E");
node_A->addAnode(node_B, 6);
node_A->addAnode(node_D, 7);
node_B->addAnode(node_C, 5);
node_B->addAnode(node_D, 8);
node_B->addAnode(node_E, -4);
node_C->addAnode(node_B, -2);
node_D->addAnode(node_C, -3);
node_D->addAnode(node_E, 9);
node_E->addAnode(node_C, 7);
node_E->addAnode(node_A, 2);
Graph* graph = new Graph();
graph->addNode(node_A);
graph->addNode(node_B);
graph->addNode(node_C);
graph->addNode(node_D);
graph->addNode(node_E);
return graph;
}
void test(string * name)
{
string * tmp = name;
delete tmp;
}
int main()
{
/*
vector<string *> test;
string* aa = new string("test");
test.push_back(aa);
delete test[0];
*/
Graph * graph = createGraph();
//Graph * reverse_graph = graph->revese();
//graph->DFS();
graph->display();
//graph->deleteNode("B");
//graph->BFS();
//graph->Dijkstra();
graph->Bellman();
graph->display();
//graph->display();
//cout<<"reverse graph: "<<endl;
//reverse_graph->DFS();
//reverse_graph->display();
//reverse_graph->strong_component();
delete graph;
//delete reverse_graph;
}
Graph Algorithms: Implementation& DFS& Strong Component& BFS & Dijkstra & Bellman Ford
最新推荐文章于 2023-03-16 12:04:52 发布