普里姆最小生成树算法

头文件:

#ifndef _PRIM_H
#define _PRIM_H
#include<limits>
#include<algorithm>
#include<assert.h>
#include<vector>
using namespace std;

//定义一个可以自我调整的优先级队列
template<typename T, typename C >
class PrioQueue
{
	public:
		PrioQueue():heapSize(0)
     	{

    	}
		void enQueue(T e)
		{
			heapSize++;
			heap.push_back(e);
			push_heap(heap.begin(),heap.end(),C());
		}
		T deQueue()
		{
			assert(heapSize>=1);
			pop_heap(heap.begin(),heap.end(),C());
			heapSize--;
			T r=heap[heapSize];
			heap.erase(heap.end()-1);
			return r;
		}
		void fix()
		{
			make_heap(heap.begin(),heap.end(),C());
		}
		bool empty()
		{
			if(heapSize>0)
				return false;
			return true;
		}
	private:
		vector<T> heap;
		int heapSize;
};


template<typename T>
class Greater
{
	public:
		bool operator()(T *x, T *y)const
		{
			return *(x)>*(y);
		}
};


pair<double*,int*>mstPrime(double*w,int n,int r)
{

	int i;
	double *key=new double[n];
	int *pi=new int[n];
	bool*poped=new bool[n];


	fill(key,key+n,numeric_limits<float>::infinity());
	fill(pi,pi+n,-1);
	fill(poped,poped+n,false);
	key[r]=0.0;
	PrioQueue<double*,Greater<double> >Q;
	for(i=0;i<n;i++)
		Q.enQueue(&key[i]);

	while(!Q.empty())
	{
		int u=static_cast<int>(Q.deQueue()-key);
		poped[u]=true;

		for(int v=0;v<n;v++)
		{
			if(!poped[v])
			{
				if(w[u*n+v]!=0.0)
				{
					if(w[u*n+v]<key[v])
					{
						pi[v]=u;
						key[v]=w[u*n+v];
					}
				}
			}
		} 
		Q.fix();
	}

	return make_pair(key,pi);
}
#endif

测试文件:

#include"prim.h"
#include<iostream>
using namespace std;
int main()
{
  double a[81]=
  {
   0,4,0,0,0,0,0,8,0,
          4,0,8,0,0,0,0,11,0,
          0,8,0,7,0,4,0,0,2,
          0,0,7,0,9,14,0,0,0,
          0,0,0,9,0,10,0,0,0,
          0,0,4,14,10,0,2,0,0,
          0,0,0,0,0,2,0,1,6,
          8,11,0,0,0,0,1,0,7,
          0,0,2,0,0,0,6,7,0
  };
       double weight=0.0,*key;
        int i,*pi,n=9;
        pair<double*,int*> r;
        r=mstPrime(a,n,0);
        key=r.first;pi=r.second;
  cout<<"普利姆算法的结果是"<<endl;
            for(i=0;i<n;i++)
               {
                   weight+=key[i];
                  if(pi[i]>=0)
                  cout<<'<'<<pi[i]<<','<<i<<">";
      cout<<endl;
   }
 
          cout<<endl<<"weight:"<<weight<<endl;
        delete[]key;
        delete [] pi;
 return 0;
}
 
//参考文献《算法导论》


你可能感兴趣的:(优先队列,普利姆最小生成树)