Graph Algorithms: Implementation& DFS& Strong Component& BFS & Dijkstra & Bellman Ford

#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;
	
	
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值