小根堆+Kruskal算法

小根堆头文件:

#include "stdafx.h"
#include <vector>
#include <iostream>
#include <iomanip>
using namespace std;
template<typename DataType>
class MinHeap
{
public:
	MinHeap();
	MinHeap(int);
	MinHeap( DataType[], int);
	MinHeap( vector<DataType> );
	bool removeTop();
	DataType getTop();
	bool insert( DataType );
	bool empty() const;
	void display() const;
private:
	int capacity;
	int size;
	DataType * topPointer;
	void displayAux( int, int ) const;
};

template<typename DataType>
MinHeap<DataType>::MinHeap()
{
	size = 0;
	capacity = 10;
	topPointer = new DataType[capacity + 1];
}

template<typename DataType>
MinHeap<DataType>::MinHeap(int capacity)
{
	size = 0;
	this.capacity = capacity;
	topPointer = new DataType[capacity + 1];
}

template<typename DataType>
MinHeap<DataType>::MinHeap(DataType arr[], int num)
{
	size = 0;
	capacity = num;
	topPointer = new DataType[capacity + 1];
	for(int i = 0; i < num; i++)
		insert( arr[i] );
}

template<typename DataType>
MinHeap<DataType>::MinHeap( vector<DataType> vec )
{
	size = 0;
	capacity = vec.size();
	topPointer = new DataType[capacity + 1];
	for(int i = 0; i < capacity; i++)
		insert( vec.at(i) );
}

template<typename DataType>
DataType MinHeap<DataType>::getTop()
{
	return *(topPointer + 1);
}


template<typename DataType>
bool MinHeap<DataType>::removeTop()
{
	*(topPointer + 1) = *(topPointer + size);
	int start = 1;
	int end = size;
	int next = 2*start;
	while( next <= end )
	{
		if( next < end )
		{
			if( *(topPointer + next) > *(topPointer + next + 1) )
				next = next + 1;
		}

		if( *(topPointer + start) > *(topPointer + next ) )
		{
			DataType tmp = *(topPointer + start);
			*(topPointer + start) = *(topPointer + next);
			*(topPointer + next) = tmp;
		}

		start = next;
		next = 2*start;
	 }
	 size--;
	 return true;
}

template<typename DataType>
bool MinHeap<DataType>::insert(DataType item)
{
	if( ++size <= capacity )
		*(topPointer + size) = item;
	else
		return false;

	int start = size;
	int next = size/2;

	while( next > 0 && *(topPointer + start) < *(topPointer + next) )
	{
		DataType tmp = *(topPointer + next);
		*(topPointer + next) = *(topPointer + start);
		*(topPointer + start) = tmp;

		start = next;
		next = start/2;
	}
	return true;
}

template<typename DataType>
bool MinHeap<DataType>::empty() const
{
	return(0 == size);
}

template<typename DataType>
void MinHeap<DataType>::display() const
{
	displayAux(1,0);
}

template<typename DataType>
void MinHeap<DataType>::displayAux(int index, int indent) const
{
	if( index <= size )
	{
		 displayAux( index * 2 , indent + 20 );
		 cout << setw(indent) << *( topPointer + index) << endl;
		 displayAux( index * 2 + 1, indent + 20 );
	}
	else
		return;
}


Kruskal头文件:

#include <iostream>
using namespace std;

class NodeEdge
{
public:
	NodeEdge():startNode(0),endNode(0),distance(0){}
	NodeEdge(int start, int end):startNode(start),endNode(end){}
	NodeEdge(int start, int end, int dis):startNode(start),endNode(end),distance(dis){}
	const NodeEdge & operator = ( const NodeEdge & );
	void display( ostream & out ) const;
public:
	int startNode;
	int endNode;
	int distance;
};

bool operator < ( const NodeEdge & left, const NodeEdge & right ) 
{
	if( left.distance < right.distance )
		return true;
	else
		return false;
}

bool operator > ( const NodeEdge & left, const NodeEdge & right ) 
{
	if( left.distance > right.distance )
		return true;
	else
		return false;
}

const NodeEdge & NodeEdge::operator = ( const NodeEdge & rightSide )
{
	if( this != & rightSide )
	{
		this->startNode = rightSide.startNode;
		this->endNode = rightSide.endNode;
		this->distance = rightSide.distance;
	}
	return *this;
}



void NodeEdge::display( ostream & out ) const
{
	out << startNode <<"<---> " << endNode <<"(" << distance <<")";
}

ostream & operator << ( ostream & out, const NodeEdge & nodeEdge )
{
	nodeEdge.display( out );
	return out;
}

Kruskal源文件:

// Kruskal.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "MinHeap.h"
#include "Kruskal.h"
#include <vector>
const int NUM = 7;
int getNodeRoot(int index);
int map[NUM][NUM] = { {0,  28,  INT_MAX,  INT_MAX,  INT_MAX,  10,  INT_MAX},
                      {28,  0,  16,  INT_MAX,  INT_MAX,  INT_MAX,  14},
					  {0,  16,  0,  12,  INT_MAX,  INT_MAX,  INT_MAX},
					  {INT_MAX,  INT_MAX,  12,  0,  22,  INT_MAX,  18},
					  {INT_MAX,  INT_MAX,  INT_MAX,  22,  0,  25,  24},
					  {10,  INT_MAX,  INT_MAX,  INT_MAX,  25,  0,  INT_MAX},
                      {INT_MAX,  14,  INT_MAX,  18,  24,  INT_MAX,  0} };
bool nodeVisited[NUM + 1] = {false}; 
int nodeRank[NUM + 1] = {0};
int nodeRoot[NUM + 1];

int _tmain(int argc, _TCHAR* argv[])
{
	//int a[10] = {4,2,6,9.1,23,54,32,95,23.3};
	//MinHeap<int> MinHeap(a,10);
	//MinHeap.display();
	vector<NodeEdge> nodeVec;
	for(int i = 0; i < NUM + 1; i++)
		nodeRoot[i] = i;
	
	for(int i = 0; i < NUM; i++)
	{
		for(int j = i + 1; j < NUM; j++)
		{
			if(map[i][j] != INT_MAX)
				nodeVec.push_back( NodeEdge(i+1,j+1,map[i][j]) );
		}
	}

	MinHeap<NodeEdge> nodeMinHeap( nodeVec );
	nodeVec.clear();

	nodeMinHeap.display();

	while( !nodeMinHeap.empty() )
	{
		NodeEdge tmp = nodeMinHeap.getTop();

		int root1 = getNodeRoot( tmp.startNode );
		int root2 = getNodeRoot( tmp.endNode );

		if( root1 != root2 )
		{		
			nodeVec.push_back( tmp );
			if( nodeRank[root1] > nodeRank[root2] )
			{
				if( nodeRoot[tmp.startNode] != root1 && nodeRoot[ nodeRoot[tmp.startNode] ] == nodeRoot[tmp.startNode] )
					nodeRoot[ nodeRoot[tmp.startNode] ] = root1;
				if( nodeRoot[tmp.endNode] != root1 && nodeRoot[ nodeRoot[tmp.endNode] ] == nodeRoot[tmp.endNode] )
					nodeRoot[ nodeRoot[tmp.startNode] ] = root1;

				nodeRoot[ tmp.startNode ] = root1;
				nodeRoot[ tmp.endNode ] = root1;
			}
			else
			{
				if( nodeRoot[tmp.startNode] != root2 && nodeRoot[ nodeRoot[tmp.startNode] ] == nodeRoot[tmp.startNode] )
					nodeRoot[ nodeRoot[tmp.startNode] ] = root2;
				if( nodeRoot[tmp.endNode] != root1 && nodeRoot[ nodeRoot[tmp.endNode] ] == nodeRoot[tmp.endNode] )
					nodeRoot[ nodeRoot[tmp.startNode] ] = root2;

				nodeRoot[ tmp.startNode ] = root2;
				nodeRoot[ tmp.endNode ] = root2;
				if( nodeRank[root1] == nodeRank[root2] )
					nodeRank[root2]++;
			}
		}
		nodeMinHeap.removeTop();
	}

	for( vector<NodeEdge>::iterator it = nodeVec.begin(); it != nodeVec.end(); it++ )
		cout << *it << endl;

	return 0;
}

        
int getNodeRoot( int index )
{
	if( nodeRoot[index] != index )
		return getNodeRoot( nodeRoot[index] );
	else
		return index;
}

参考程序:
http://www.codeproject.com/Articles/163618/Kruskal-Algorithm


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值