zoukankan      html  css  js  c++  java
  • Prim算法

    用c++实现了Prim算法。用了c++的优先队列。

    代码仅供参考:

    #include <iostream>
    #include <string>
    #include <stack>
    #include <fstream>
    #include <sstream>
    #include <ctime>
    #include <vector>
    #include <queue>
    #include <algorithm>
    using namespace std;
    /**********边表************/
    class EdgeNode
    {
    public:
    	int adjvex;
    	int cost;
    	int head;
    	EdgeNode *next;
    	EdgeNode(int _head, int _adj, int _cost,EdgeNode *n = NULL) : head(_head), adjvex(_adj), cost(_cost), next(n) {}
    };
    /*=========顶点表============*/
    class VertexNode
    {
    public:
    	int data;
    	EdgeNode *firstEdge;
    	VertexNode()
    	{
    		firstEdge = NULL;
    	}
    };
    /*********自定义比较函数(优先队列使用)************/
    class mycompare
    {
    	bool reverse;
    public:
    	mycompare(const bool &re = true)
    	{
    		reverse = re;	
    	}
    	bool operator() (EdgeNode *a, EdgeNode *b) const
    	{
    		//从小到大排列, 优先队列,!mycompare,按照cost的从小到大排列
    		if(reverse) return (a->cost > b->cost); 
    		else {
    			return (a->cost < b->cost);
    			//从小到大排列, 优先队列,!mycompare,按照cost的从大到小排列
    		}
    
    	}
    
    };
    /*********无向图的数据结构*************/
    class Graph 
    {
    public:
    /*********初始化图的邻接表数据***************/
    	Graph()
    	{
    		ifstream fin("pp.txt");
    		string line;
    		stringstream stream;
    		if(getline(fin, line))
    		{
    			stream.clear();
    			stream << line;
    			stream >> numVertexes;
    			stream >> numEdges;
    		}
    		init_adjList();
    		while(getline(fin, line))
    		{
    			int vertex, adjacent,  _cost;
    			stream.clear();
    			stream << line;
    			stream >> vertex;
    			stream >> adjacent;
    			stream >> _cost;
    			addEdge(vertex, adjacent, _cost);			
    		}
    	}
    /********初始化邻接表的顶点表*******/
    	void init_adjList()
    	{
    		adjList.resize(numVertexes);
    		for(int i = 0; i < numVertexes; i++)
    		{	
    			adjList[i].data = i;
    		}		
    	}
    
    
    /************加边,头插法*****************/
    	void addEdge(int a, int b, int _cost)
    	{
    		EdgeNode *enode1 = new EdgeNode(a-1, b-1, _cost, NULL);
    		EdgeNode *enode2 = new EdgeNode(b-1, a-1, _cost, NULL);
    		adjList[a-1].data = a-1;
    		enode1->next = adjList[a-1].firstEdge;
    		adjList[a-1].firstEdge = enode1;
    		adjList[b-1].data = b-1;
    		enode2->next = adjList[b-1].firstEdge;
    		adjList[b-1].firstEdge = enode2;
    	}
    /************打印看结果************/
    	void print()
    	{
    		ofstream fout;
    		fout.open("primoutput.txt");
    		for(int i = 0; i < numVertexes; i++)
    		{
    			fout << "vertex:" << adjList[i].data << " adj:" ;
    			EdgeNode *tmp = new EdgeNode(0, 0, 0 );
    			tmp = adjList[i].firstEdge;
    			while(tmp)
    			{
    				fout << tmp->adjvex << "cost: " << tmp->cost << " ";
    				tmp = tmp->next;
    			}
    			fout << endl;
    		}
    	}
    /*********************************/
    public:
    	int numVertexes; //顶点数目
    	int numEdges;	 //边数目
    	vector<VertexNode> adjList;   //图的邻接表
    };
    /***********prim算法实现**********/
    class Prims
    {
    public:
    	Prims(Graph graph)
    	{
    		int s = 0;
    		length = graph.numVertexes; //顶点数目
    		tree.resize(length); 
    		marked.push_back(s); //将初始顶点加入最小生成树中
    		pq.push(graph.adjList[s].firstEdge); //将初始顶点的第一条边加入队列
    		while(!pq.empty())
    		{
    			EdgeNode *p = new EdgeNode(0,0,0);
    			p = graph.adjList[s].firstEdge;
    			while(p)
    			{
    				if(!is_marked(p->adjvex))
    				{
    					pq.push(p);
    				}
    				p = p->next;
    			}
    
    			EdgeNode *p1 = new EdgeNode(0,0,0);
    			p1 = pq.top();
    			pq.pop();
    			s = p1->adjvex;
    			if(!is_marked(s)) //如果没有加入进最小生成树
    			{
    				marked.push_back(p1->adjvex);
    				tree[p1->head].push_back(p1->adjvex); //将边加入最小生成数
    				sum += p1->cost;  //cost的累加
    			}
    		
    		}
    
    	}
    /*******************判断是否加入最小生成树***************/	
    	bool is_marked(int a)
    	{
    	
    		for(int i = 0; i < marked.size(); i++)
    		{
    			if(marked[i] == a)
    			{
    				return true;
    			}
    		}
    		return false;
    	}
    /***************输出看结果**************/
    	void write()
    	{
    		ofstream fout;
    		fout.open("tree.txt");
    		for(int i = 0; i < length; i++)
    		{
    			fout << "tree[" << i << "]: " ;
    			for(int j = 0; j < tree[i].size(); j++)
    			{
    				fout << tree[i][j] << " ";
    			}
    			fout << endl;
    		}
    	}
    
    
    public:
    	int length;
    	int sum = 0;
    	vector<int> marked;//最小生成树木的顶点表
    	vector<vector<int> > tree; //最小生成树的边 ,数组存储
    	priority_queue<EdgeNode*, vector<EdgeNode*>, mycompare> pq; //优先队列
    };
    
    
    int main()
    {
    	Graph graph;
    	graph.print();
    	Prims _prims(graph);
    	_prims.write();
    	cout << "sum: " << _prims.sum << endl;
    	return 0;
    }
    

      

    The Safest Way to Get what you Want is to Try and Deserve What you Want.
  • 相关阅读:
    vue之插槽
    微信公众号-关注和取消关注
    微信公众号-消息响应
    微信公众号-验证接入
    微信公众号-开发工具natapp内网穿透安装和使用
    windows安装PHP5.4+Apache2.4+Mysql5.5
    php各种主流框架的优缺点总结
    php框架的特性总结
    什么是php?php的优缺点有哪些?与其它编程语言的优缺点?
    二进制、八进制、十进制、十六进制之间转换
  • 原文地址:https://www.cnblogs.com/Shinered/p/9129874.html
Copyright © 2011-2022 走看看