图的头文件(详解)包含10几种函数以及实现

#include<iostream>
#include<list> 
#include<fstream>
using namespace std;
const double MAXCOST = 10000;
struct PathData
	{
		int start,dest;
		double cost;
		operator double()const{return cost;}
		
	} ;
template <class T>
class  Graph
{
	struct EdgeNode
	{
		int dest;
		double cost;
		operator int() { return dest; }
	};
	T* VA;
	list<EdgeNode>* HL;
	int sizeV, sizeE;
	int maxV;

public:
	Graph(int n = 100) :sizeV(0), sizeE(0), maxV(n)
	{
		VA = new T[n];
		HL = new list<EdgeNode>[n];
	}
	~Graph()
	{
		delete[]VA;
		delete[]HL;
	}
	int Empty()const { return sizeV == 0; }
	int Full()const { return sizeV == maxV; }
	int SizeV()const { return sizeV; }
	int SizeE()const { return sizeE; }
	int FindNode(const T& v)const;
	bool StoreNode(T&v,int pos)const; 
	double GetCost(const T& vl, const T& v2)const;
	bool InsertV(const T& v);
	bool InsertE(const T& v1, const T& v2, double w);
	bool DeleteV(const T& v);
	bool DeleteE(const T& v1, const T& v2);
	void ReadGraph(const char* filename);
	void WriteGraph(const char* filename);
	void BuildHeap(PathData*E,int size)const;
	void PercolateDown(PathData*E,int pos,int size)const;
	bool Prim(const T&v,PathData* E,int ne)const;
	friend istream& operator>>(istream& istr,Graph<T>& g)
	{
			char s[50];
        	int n;
        	double w;
	        T v1,v2;
	        istr>>s>>n;
	        for(int i=1;i<=n;++i)
        	{
	        	istr>>v1;
		        g.InsertV(v1);
         	}
	        istr>>s>>n;
        	for(int i=1;i<=n;++i)
         	{
	       	istr>>v1>>v2>>w;
	     	g.InsertE(v1,v2,w);
		
	        } 
         	return istr;
	}
	friend ostream& operator<<(ostream& ostr,const Graph<T>&g)
	{
		
        	for(int i=0;i<g.sizeV;i++)
	        {
	     	ostr<<i<<'-'<<g.VA[i]<<':';
	        typename list<Graph<T>::EdgeNode>::iterator first=g.HL[i].begin(),last=g.HL[i].end();
	     	for(;first!=last;++first)
		    	ostr<<'('<<(*first).dest<<','<<(*first).cost<<')'<<' ';
		   	ostr<<endl;
	        }
		      return ostr;
	}
};
template <class T>
int Graph<T>::FindNode(const T& v)const
{
	for (int i = 0; i < sizeV; i++)
		if (VA[i] == v)
			return i;
	return 0;
}
template<class T>
bool Graph<T>::StoreNode(T&v, int pos)const
{
	if(pos<0||pos>sizeV-1)
	   return 0;
	 v=VA[pos];
	 return 1;
	
	
} 
template<class T>
double Graph<T>::GetCost(const T& v1, const T& v2)const
{
	int si = FindNode(v1), dj = FindNode(v2);
	if (si < 0 || si >= sizeV || dj < 0 || dj >= sizeV || dj == si)
	{
		return 0;
	}
	typename list<EdgeNode>::const_iterator first = HL[si].begin(), last = HL[si].end();
	for (; first != last; ++first)
	{
		if ((*first).dest == dj)
			return (*first).cost;
	}
	return 0;
}
template<class T>
bool Graph<T>::InsertV(const T& v)
{
	if (sizeV == maxV)
	{
		return 0;
	}
	VA[sizeV] = v;
	sizeV++;
	return 1;
}
template<class T>
bool Graph<T>::InsertE(const T& v1, const T& v2, double w)
{
	int si = FindNode(v1), dj = FindNode(v2);
	if (si < 0 || dj < 0 || si == dj)
	{
		return 0;
	}
	EdgeNode en;
	en.dest = dj;
	en.cost = w;
	HL[si].insert(HL[si].end(), en);
	sizeE++;
	return 1;
}
template <class T>
bool Graph<T>::DeleteE(const T& v1, const T& v2)
{
	int si = FindNode(v1), dj = FindNode(v2);
	if (si < 0 || dj < 0 || si == dj)
	{
		return 0;
	}
	typename list<EdgeNode>::iterator first = HL[si].begin(), last = HL[si].end();
	for (; first != last; ++first)
	{
		if ((*first).dest == dj)
		{
			HL[si].Erase(first);
			sizeE--;
			return 1;
		}
	}

	return 0;
}
template<class T>
bool Graph<T>::DeleteV(const T& v)
{
	int si = FindNode(v);
	if (si<0 || si>sizeV - 1)
		return 0;
	int size = HL[si].size();
	for (int i = si; i<sizeV-1; i++)
	{
		VA[i] = VA[i + 1];
		HL[i] = HL[i + 1];
	}
	HL[sizeV - 1].clear();
	sizeV--;
	sizeE = sizeE - size;
	typename list<EdgeNode>::iterator first, last;
	for (int i = 0; i < sizeV; i++)
	{
		first = HL[i].begin(),last = HL[i].end();
		for (; first != last; ++first)
		{
			if ((*first).dest ==si)
			{
				HL[i].erase(first);
				sizeE--;
				break;
			}
		}

	}
	for (int i = 0; i < sizeV; i++)
	{
		first = HL[i].begin(), last = HL[i].end();
		for (; first != last; ++first)
		{
			if ((*first).dest > si)
			{
				(*first).dest--;
			}
		}
	}
    return 1;
}
template <class T>
void Graph<T>::ReadGraph(const char* filename)
{
	char str[50];
	int n;
	double w;
	T v1, v2;
	ifstream fin;
	fin.open(filename, ios::in);
	if (!fin)
	{
		cout << "cannot open" << filename << endl;
		exit(1);
	}
	fin >> str >> n;
	for (int i = 1; i <= n; ++i)
	{
		fin >> v1;
		InsertV(v1);
	}
	fin >> str >> n;
	for (int i = 1; i <=n; ++i)
	{
		fin >> v1 >> v2 >> w;
		InsertE(v1, v2, w);
	}
}
template<class T>
void Graph<T>::WriteGraph(const char* filename)
{
	ofstream fout;
	fout.open(filename, ios::out);
	if (!fout)
	{
		cout << "cannot open" << filename << endl;
		exit(1);
	}
	for (int i = 0; i < sizeV; i++)
	{
		fout << i << '-' << VA[i] << ":";
		typename list<Graph<T>::EdgeNode>::iterator first = HL[i].begin(), last = HL[i].end();
		for (; first != last; ++first)
		{
			fout << '(' << (*first).dest << ',' << (*first).cost << ')' << ' ';
		}
			fout << endl;
	}

}
template <class T>
void Graph<T>::PercolateDown(PathData*E,int pos,int size)const
{
	int p=pos,c=2*p+1;
	PathData temp=E[p];
	while(c<size)
	{
		if(c+1<size&&E[c+1]<E[c])//隐式调用成员转换函数来比较权 
		   ++c;
        if(temp<E[c])
           break;
        else
        {
        	E[p]=E[c];
        	p=c;
        	c=2*p+1;
		}
	}
	E[p]=temp;
}
template <class T>
void Graph<T>::BuildHeap(PathData*E,int size)const
{
	for(int i=size/2-1;i>=0;i--)
	 PercolateDown(E,i,size);
	 
}
template <class T>
bool Graph<T>::Prim(const T&v,PathData*E,int ne)const
{
	int i,j,s,ns;
	PathData item;
	double cost;
	s=FindNode(v);
	if(s<0||s>sizeV-1)
	  return 0;
	int id=0;
	for(int i=0;i<=ne;i++)
	{
		if(i!=s)
		{
			item.start=s;
			item.dest=i;
			cost=GetCost(VA[s],VA[i]);
			item.cost=(cost==0?MAXCOST:cost);
			E[id++]= item; //???????????
		} 
	}
	int count=0;
	BuildHeap(E,ne);//对候选边集建堆,取最小的 
	for(int i=0;i<ne;i++)
	{
		if(E[0]<MAXCOST)//调用成员转换函数比较权 
		 count++;
	    ns=E[0].dest;
	    for(int j=1;j<ne-i;j++)
	    {
	    	cost=GetCost(VA[ns],VA[E[j].dest]);
	    	cost=(cost==0?MAXCOST:cost);
	    	if(E[j]>cost)
	    	{
	    		E[j].cost=cost;
				E[j].start=ns; 
	    		
			}
		}
		item=E[0];
		E[0]=E[ne-1-i];
		E[ne-1-i]=item;
		PercolateDown(E,0,ne-1-i);
    } 
    return (count==ne?1:0);
} 
template <class T>
void Display(const Graph<T>&g,PathData*E,int ne)
{
	T v1,v2;
	for(int i=ne-1;i>-1;i--)
	{
		g.StoreNode(v1,E[i].start);
		g.StoreNode(v2,E[i].dest);
		E[i].cost=g.GetCost(v1,v2);
		cout<<'('<<v1<<','<<v2<<','<<E[i].cost<<')'<<endl;
	}
}
int main()
{
	Graph<char> G;
	G.ReadGraph("Graphmin.txt");
	cout<<G;
	PathData *E=new PathData[G.SizeV()-1];
	if(G.Prim('A',E,G.SizeV()-1))
	{
		cout<<"Prim:\n";
		Display(G,E,G.SizeV()-1); 
   }
	return 0;
}






















  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大脚牛向前冲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值