• 最小生成树的Prim算法(待修正版)


    // prim.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include<iostream>
    #include<queue>
    using namespace std;
    typedef int Vertex;
    #define NotAVertex 0
    #define INF 65536
    #define numOfVertex 4
    
    //定义链表节点////////////////////////////////////
    typedef struct TreeNode *Position;
    struct TreeNode {
    	Vertex vertex;
    	int weight;
    	Position Next;
    };
    
    //定义邻接表结构/////////////////////////////////////
    typedef struct adjaceency_list *adjaceency;
    struct adjaceency_list {
    	int numVertex;      //大小
    	Position* table;   //表地址
    };
    
    //邻接表初始化函数////////////////////////////////////
    adjaceency initAdjaceency_list(int numVertex)
    {
    	//申请一个邻接表地址,给邻接表赋初值
    	adjaceency adja = (adjaceency)malloc(sizeof(adjaceency_list));
    	adja->numVertex = numVertex;
    	if (adja == NULL)
    		cout << "Error";
    
    	//申请一个table地址
    	adja->table = (Position*)malloc(sizeof(Position)*(adja->numVertex + 1));
    	if (adja->table == NULL)
    		cout << "Error";
    
    	//给邻接表每一个表项添加一个链表表头
    	for (int i = 1; i <= adja->numVertex; i++) {
    		adja->table[i] = (Position)malloc(sizeof(TreeNode));
    		if (adja->table[i] == NULL)
    			cout << "Error";
    		else {
    			adja->table[i]->vertex = i;
    			adja->table[i]->weight = 0;       //给每个邻接表项的链表头的权重设为0
    			adja->table[i]->Next = NULL;
    		}
    	}
    	return adja;
    }
    
    //邻接表的插入函数,制定一个顶点per_ver,把邻接的顶点aft_ver插入其后//////////////////////////////////
    void Insert(adjaceency adja, Vertex per_ver, Vertex aft_ver, int weight)
    {
    	//申请一个链表节点地址
    	Position inser = (Position)malloc(sizeof(TreeNode));
    	if (inser == NULL)
    		cout << "Error";
    
    	//从头插入,修改指针
    	inser->vertex = aft_ver;
    	inser->weight = weight;                   //从per_ver指向aft_ver的权重
    	inser->Next = adja->table[per_ver]->Next;
    	adja->table[per_ver]->Next = inser;
    }
    
    //打印邻接表//////////////////////////////////////////
    void print(adjaceency adja)
    {
    	cout << "Vertex" << endl;
    	for (int i = 1; i <= adja->numVertex; i++)
    	{
    		Position p = adja->table[i];
    		while (p != NULL) {
    			cout << p->vertex << '	';
    			p = p->Next;
    		}
    		cout << endl;
    	}
    	cout << endl;
    }
    
    
    //定义顶点结构////////////////////////////////
    struct Vertexs
    {
    	Vertex ver_num;         //顶点的标号
    	int minWeight;          //该顶点连接到树上的最小权重
    	bool inQ;               //是否在优先队列Q中
    	Vertex verFather;       //该顶点的父亲
    
    	friend bool operator< (Vertexs ver1, Vertexs ver2)  //重定义运算符
    	{
    		return ver1.minWeight> ver2.minWeight;   //因为优先队列默认是<,因此若要形成最小堆,用>来重定义<
    	}
    };
    
    //最小生成树的Prim算法/////////////////////////////
    void MST_PRIM(adjaceency adja, Vertex start)
    {  
    	//定义顶点数组以及初始化顶点
    	Vertexs ver[numOfVertex + 1];
    	for (int i = 1; i <= numOfVertex; i++)
    	{
    		ver[i].minWeight = INF;
    		ver[i].ver_num = i;
    		ver[i].inQ = true;
    		ver[i].verFather = NULL;
    	}
    	ver[start].minWeight = 0;
    
    	//把所有顶点入优先队列
    	priority_queue<Vertexs> verPriority;
    	for (int i = 1; i <= numOfVertex; i++)
    	{
    		verPriority.push(ver[i]);
    	}
    
    	//出队操作
    	Vertexs verTemp;
    	while (!verPriority.empty())
    	{
    		//最小权重值的先出队
    		verTemp = verPriority.top();
    		verPriority.pop();
    		verTemp.inQ = false;
    
    		Position p = adja->table[verTemp.ver_num]->Next;
    		while (p)
    		{
    			if (ver[p->vertex].inQ&&p->weight < ver[p->vertex].minWeight)
    			{
    				ver[p->vertex].minWeight = p->weight;                    //这部分有问题,
    				ver[p->vertex].verFather = verTemp.ver_num;             //这里不能改变优先队列里面的元素
    			}
    			p = p->Next;
    		}
    	}
    
    	//打印最小生成树
    	for (int i = numOfVertex; i >= 1; i--)
    	{
    		cout << ver[i].ver_num << "------" << ver[i].verFather << endl;;
    	}
    	
    }
    
    int main()
    {
    	//初始化邻接表////////////////////////////////////////
    	adjaceency adja = initAdjaceency_list(numOfVertex);
    	Insert(adja, 1, 3, 4); Insert(adja, 1, 4, 1); Insert(adja, 1, 2, 2);
    	Insert(adja, 2, 3, 10); Insert(adja, 2, 4, 3); Insert(adja, 2, 1, 2);
    	Insert(adja, 3, 4, 2); Insert(adja, 3, 1, 4); Insert(adja, 3, 2, 10);
    	Insert(adja, 4, 3, 2); Insert(adja, 4, 2, 3); Insert(adja, 4, 1, 1);
    	print(adja);
    
    	MST_PRIM(adja, 1);
    
    	while (1);
        return 0;
    }
    

      

  • 相关阅读:
    从自然数到有理数
    付费版乐影音下载器使用方法
    Avtiviti之流程变量
    activity(工作流)初步学习记录
    IntelliJ IDEA安装Activiti插件并使用
    golang 性能测试
    Golang性能测试工具PProf应用详解
    java连接ZK的基本操作
    会员体系、积分、等级
    Flink基本概念
  • 原文地址:https://www.cnblogs.com/linear/p/6728953.html
Copyright © 2020-2023  润新知