单源最短路径BellmanFord算法实现文件C++

 
//	graphRepresentAsAdjacentList.cpp -- mplement file
#include "stdafx.h"
#include "graphRepresentAsAdjacentList.h"

//	Purpose:
//	Define methods of class "graphRepresentAsAdjacentList".

//	Private methods:
//	---------------------
graphRepresentAsAdjacentList ::Vertex * graphRepresentAsAdjacentList ::m_makeVertex (int indexInAdjacentList, int weight)
{
	Vertex * newVertex = new Vertex ;
	if (newVertex != NULL)
	{
		newVertex ->indexInAdjacentList = indexInAdjacentList ;
		newVertex ->weight = weight ;
		newVertex ->next = NULL ;
	}

	return newVertex ;
}
//	---------------------

//	---------------------
//	Assume the graph has been imported perfectly and
//	0 <= sourceVertex < m_size.
void graphRepresentAsAdjacentList ::m_initializeSingleSource (int sourceVertex)
{
	for (vector<int> ::iterator iter = m_distanceVector.begin(); iter != m_distanceVector.end(); ++iter)
	{
		*iter = Infinity ;
	}
	for (vector<int> ::iterator iter = m_parentVector.begin(); iter != m_parentVector.end(); ++iter)
	{
		*iter = Nil ;
	}
	m_distanceVector[sourceVertex] = 0 ;
}
//	---------------------

//	---------------------
int graphRepresentAsAdjacentList ::m_distanceBetweenTwoVertexes (int startVertex, int endVertex)
{
	Vertex * scan = m_adjacentListVector[startVertex].next ;

	while (scan != NULL)
	{
		if (endVertex == scan ->indexInAdjacentList)
			return scan ->weight ;
		scan = scan ->next ;
	}
	
	return Infinity ;
}
//	---------------------

//	---------------------
//	Assume both startVertex and endVertex are in the correct range.
void graphRepresentAsAdjacentList ::m_relax (int startVertex, int endVertex)
{
	if (m_distanceVector[endVertex] > m_distanceVector[startVertex] + m_distanceBetweenTwoVertexes(startVertex, endVertex))
	{
		m_distanceVector[endVertex] = m_distanceVector[startVertex] + m_distanceBetweenTwoVertexes(startVertex, endVertex) ;
		m_parentVector[endVertex] = startVertex ;
	}
}
//	---------------------

//	Public methods:
//	---------------------
graphRepresentAsAdjacentList ::graphRepresentAsAdjacentList (int size)
{
	if (size <= 0)
	{
		std ::cerr << "Wrong size." << std ::endl ;
		return ;
	}
	m_size = size ;
	m_currentSize = 0 ;
	//	Set the size of following vertexes only.
	m_parentVector.resize(m_size) ;
	m_distanceVector.resize(m_size) ;
}
//	---------------------

//	---------------------
graphRepresentAsAdjacentList ::~graphRepresentAsAdjacentList (void)
{
	m_adjacentListVector.erase(m_adjacentListVector.begin(), m_adjacentListVector.end()) ;
}
//	---------------------

//	---------------------
bool graphRepresentAsAdjacentList ::importAVertex (const std ::vector<int> & indexVector, const std ::vector<int> & weightVector)
{
	static Vertex vertex ;

	if (m_currentSize < m_size)
	{
		vertex.indexInAdjacentList = m_currentSize ;
		//	W[u][u] is 0 and m_adjacentListVector[m_currentSize] is the vertex u.
		vertex.weight = 0 ;
		vertex.next = NULL ;
		m_adjacentListVector.push_back(vertex) ;
		if (indexVector.size() != 0)
		{
			vector<int> ::size_type iIndex = 0 ;
			vector<int> ::size_type iWeight = 0 ;
			Vertex * newVertex = m_makeVertex(indexVector[iIndex++], weightVector[iWeight++]) ;
			if (newVertex != NULL)
			{
				m_adjacentListVector[m_currentSize].next = newVertex ;
				while (iIndex != indexVector.size())
				{
					Vertex * anotherNewVertex = m_makeVertex(indexVector[iIndex++], weightVector[iWeight++]) ;
					if (anotherNewVertex != NULL)
					{
						newVertex ->next = anotherNewVertex ;
						newVertex = anotherNewVertex ;
					}
					else
					{
						return false ;
					}
				}
			}
			else
			{
				return false ;
			}
		}
		++m_currentSize ;
		return true ;
	}
	std ::cerr << "All vertexes have been imported." << std ::endl ;

	return false ;
}
//	---------------------
bool graphRepresentAsAdjacentList ::bellmanFord (int sourceVertex)
{
	m_initializeSingleSource(sourceVertex) ;
	//	The loop runs m_size - 1 times.
	for (int i = 0; i != m_size - 1; ++i)
	{
		//	For each edge in the graph.
		for (vector<Vertex> ::const_iterator iter = m_adjacentListVector.begin(); iter != m_adjacentListVector.end(); ++iter)
		{
			Vertex * scan = iter ->next ;
			while (scan != NULL)
			{
				//	A edge has been found.
				m_relax(iter ->indexInAdjacentList, scan ->indexInAdjacentList) ;
				scan = scan ->next ;
			}
		}
	}
	//	Test if there is a negative circle.
	for (vector<Vertex> ::const_iterator iter = m_adjacentListVector.begin(); iter != m_adjacentListVector.end(); ++iter)
	{
		Vertex * scan = iter ->next ;
		while (scan != NULL)
		{
			if (m_distanceVector[scan ->indexInAdjacentList] >
				m_distanceVector[iter ->indexInAdjacentList] + m_distanceBetweenTwoVertexes(iter ->indexInAdjacentList, scan ->indexInAdjacentList))
			{
				return false ;
			}
			scan = scan ->next ;
		}
	}

	return true ;
}
//	---------------------

//	---------------------
void graphRepresentAsAdjacentList ::printEachShortestPathValueFromSourceVertex (int startVertex)
{
	vector<Vertex> ::size_type i = 0 ;
	while (i != startVertex)
	{
		std ::cout << "V[" << startVertex << "] ->" << "V[" << i << "]: " << m_distanceVector[i] << std ::endl ;
		++i ;
	}
	i = startVertex + 1 ;
	vector<Vertex> ::size_type size = m_size ;
	while (i != size)
	{
		std ::cout << "V[" << startVertex << "] ->" << "V[" << i << "]: " << m_distanceVector[i] << std ::endl ;
		++i ;
	}
}
//	---------------------

//	---------------------
void graphRepresentAsAdjacentList ::printGraph (void)
{
	for (vector<Vertex> ::size_type i = 0; i != m_adjacentListVector.size(); ++i)
	{
		std ::cout << "V[" << i << "] ->" ;
		Vertex * scan = m_adjacentListVector[i].next ;
		while (scan != NULL)
		{
			std ::cout << "V[" << scan ->indexInAdjacentList << "] weight: " << scan ->weight << " ->" ;
			scan = scan ->next ;
		}
		std ::cout << std ::endl ;
	}

}
//	---------------------

//	End of file.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值