数据结构 图 最小子树C/C++ 普里姆算法(Prime)

最小子树有两个最常用的方法

1、Prime算法

2、克鲁斯卡尔算法

这里,小编就先介绍 Prime算法

思路:

将 图存入 邻接表中,这时 创建一个额外空间,是一个结构体数组

取一个点为树根,开始,每次找出最小权值

这中算法是  树一点点长大,从根,开始,直至最后整个树建立

 

// 数组+链表 图.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include "Linked.h"
#include "Graph.h"

const int INFTY = 10000;

typedef struct List {
	int closeVex;	// 前一个结点 index
	int lowWeight;	// 权值 ,初始值为 INYFTY
	bool flag;		//标记当前下标是否被使用
}List;

// 初始化 图,即 将图中的信息存入
void intiGraph(Graph<int>);
//初始化三元组 一维数组,closeVex = -1,lowWeight = INFTY,flag = false
void initList(List [],int);
// 输出三元组 数组
void outputList(List[], int);
// 普里姆算法 排序
void prim(int ,List [],int,Graph<int>);
// 通过给定最小权值,遍历 其 有效连接结点,比较权值,最小值默认为 0
int primTraverse(List list[],int length,int index, Linked<int> linked);
// 求 最下权值 index
int min(List list[], int length);
/*
0:5 2 1
1:3 5 0
2:4 0
3:4 5 1
4:3 5 2
5:4 3 1 0
*/
int main(void)
{
	//cout << "请输入数组的长度:";
	int length  = 6;
	//cin >> length;
	Graph<int> graph = Graph<int>(length);
	intiGraph(graph);
	graph.print();
	List * list = new List[length];
	initList(list,length);
	prim(0,list,length,graph);
	//cout << "fital resutl:" << endl;
	outputList(list, length);

	return 0;
}

int min(List list[], int length) {
	int index;
	for (int i = 0; i < length; i++)
	{
		if (!list[i].flag)
		{
			index = i;
			break;
		}
	}
	int min = list[index].lowWeight;
	for (int i = 0; i < length; i++)
	{
		if (min > list[i].lowWeight && list[i].flag==false) {
			//cout << "min = " << min << "  list[i].lowWeight=" << list[i].lowWeight << endl;
			index = i;
			min = list[i].lowWeight;
		}
	}
	return index;
}

int primTraverse(List list[],int length,int index, Linked<int> linked) {
	//cout << "打印当前链表:"; linked.print();
	Node<int> * tmpPtr = linked.head.next;
	while (tmpPtr)
	{
		if (!list[tmpPtr->data].flag)
		{
			//cout <<"list[tmpPtr->data].lowWeight="<< list[tmpPtr->data].lowWeight << "   tmpPtr->weight="<< tmpPtr->weight << endl;
			if (list[tmpPtr->data].lowWeight > tmpPtr->weight)
			{
				list[tmpPtr->data].lowWeight = tmpPtr->weight;
				list[tmpPtr->data].closeVex = tmpPtr->data;
			}
		}
		tmpPtr = tmpPtr->next;
	}
	//outputList(list, length);
	//cout << "\n####################"<<endl;
	int small = min(list, length);
	//cout << "small = " << small << endl;
	return small;
}

void prim(int k,List list[],int length, Graph<int> graph) {
	
	int index = 0;
	for (int i = 0; i < length - 1; i++)	// 默认从第一个结点开始
	{
		list[index].flag = true;
		//cout << "index = " << index << endl;
		index = primTraverse(list,length, index, graph.list[index]);
	}
}

void outputList(List list[], int length) {
	for (int i = 0; i < length; i++)
	{
		cout <<i<<":\t" <<list[i].closeVex << "\t"<< list[i].lowWeight<<  "\t"<<list[i].flag << endl ;
	}
}

void initList(List list[],int length) {
	for (int i = 0; i < length; i++)
	{
		list[i].closeVex = -1;
		list[i].lowWeight = INFTY;
		list[i].flag = false;
	}
}

void intiGraph(Graph<int> graph) {
	graph.put(0, 1, 7);
	graph.put(0, 2, 10);
	graph.put(0, 5, 4);

	graph.put(1, 0, 7);
	graph.put(1, 5, 6);
	graph.put(1, 3, 8);

	graph.put(2, 0, 10);
	graph.put(2, 4, 2);

	graph.put(3, 1, 8);
	graph.put(3, 5, 5);
	graph.put(3, 4, 9);

	graph.put(4, 2, 2);
	graph.put(4, 5, 7);
	graph.put(4, 3, 9);

	graph.put(5, 0, 4);
	graph.put(5, 1, 6);
	graph.put(5, 3, 5);
	graph.put(5, 4, 7);
}


#pragma once
#include "Linked.h"

template<class Type>
class Graph
{
	int m_size;
public:
	Linked<Type> * list;
	Graph();
	void put(int index,Type data, int weight);
	void print(int index);
	void print();
	void outputWeight(int index);
	void outputWeight();
	void inputWeight(int index);
	void inputWeight();
	Graph(int size);
	~Graph();
};

template<class Type>
inline Graph<Type>::Graph()
{
	m_size = 16;
	list = new Linked<Type>[m_size];
}

template<class Type>
inline void Graph<Type>::put(int index, Type data,int weight)
{
	if (index < 0 || index >= m_size) {
		cout << "越界" << endl;
		return;
	}
	list[index].put(data,weight);
}

template<class Type>
inline void Graph<Type>::print(int index)
{
	list[index].print();
}

template<class Type>
inline void Graph<Type>::print()
{
	cout << "打印邻接表" << endl;
	for (int i = 0; i < m_size; i++)
	{
		cout << i << ":";
		list[i].print();
	}
	cout << endl;
}

template<class Type>
inline void Graph<Type>::outputWeight(int index)
{
	cout << index << "出度:" << list[index].outputWeight() << endl;
}

template<class Type>
inline void Graph<Type>::outputWeight()
{
	cout << "出度" << endl;
	for (int i = 0; i < m_size; i++)
	{
		outputWeight(i);
	}
	cout << endl;
}

template<class Type>
inline void Graph<Type>::inputWeight(int index)
{
	int count = 0;
	for (int i = 0; i < m_size; i++)
	{
		if (i != index) {
			count += list[i].inputWeight(index);
		}
	}
	cout << index << " 入度:" << count << endl;
}

template<class Type>
inline void Graph<Type>::inputWeight()
{
	cout << "入度" << endl;
	for (int i = 0; i < m_size; i++)
	{
		inputWeight(i);
	}
	cout << endl;
}

template<class Type>
inline Graph<Type>::Graph(int size)
{
	m_size = size;
	list = new Linked<Type>[m_size];
}

template<class Type>
inline Graph<Type>::~Graph()
{
	//delete list;
}

#pragma once
template<class Type>
struct Node {
	Type data;
	int weight;
	struct Node * next;
};

template<class Type>
class Linked
{
public:
	Node<Type> head;
	void put(Type data, int weight);
	void print();
	int outputWeight();
	int inputWeight(Type data);
	Linked();
	~Linked();
};

template<class Type>
inline void Linked<Type>::put(Type data,int weight)
{
	Node<Type> * nodeTmp = new Node<Type>;
	nodeTmp->data = data;
	nodeTmp->weight = weight;
	nodeTmp->next = head.next;
	head.next = nodeTmp;
}

template<class Type>
inline void Linked<Type>::print()
{
	if (head.next == NULL) {
		cout << "NULL" << endl;
		return;
	}
	Node<Type> * tmpPtr = head.next ;
	while (tmpPtr)
	{
		cout << tmpPtr->data << " ";
		tmpPtr = tmpPtr->next;
	}
	cout << endl;
}

template<class Type>
inline int Linked<Type>::outputWeight()
{
	int count = 0;
	if (head.next == NULL) {
		return count;
	}
	Node<Type> * tmpPtr = head.next;
	while (tmpPtr)
	{
		count += tmpPtr->weight;
		tmpPtr = tmpPtr->next;
	}
	return count;
}

template<class Type>
inline int Linked<Type>::inputWeight(Type data)
{
	int count = 0;
	if (head.next == NULL) {
		return count;
	}

	Node<Type> * tmpPtr = head.next;
	while (tmpPtr)
	{
		if (tmpPtr->data == data)
		{
			count += tmpPtr->weight;
		}
		tmpPtr = tmpPtr->next;
	}
	return count;
}

template<class Type>
inline Linked<Type>::Linked()
{
	head.data = 0;
	head.weight = 1;
	head.next = NULL;
}

template<class Type>
inline Linked<Type>::~Linked()
{
	//delete head;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值