• 图——普里姆算法——构建最小生成树(采用邻接矩阵的方式存储)


    include "stdafx.h"

    #include<iostream>
    #include<vector>
    #include<string>
    #include<queue>
    #include<stack>
    #include<cstring>
    #include<string.h>
    #include<deque>
    #include <forward_list>
    #include<set>
    #include<list>
    
    using namespace std;
    
    typedef struct
    {
    	vector<int> vexs;//顶点表
    	vector<vector<int>> arcs;//边表
    	int vexnums, arcnums;
    }AMGraph; //邻接矩阵表示一个图
    
    class Solution {
    public:
    	void CreateGraph(AMGraph &G)
    	{
    		int num = 0;
    		cout << "请输入顶点个数:";
    		cin >> num;
    		G.vexnums = num;
    		cout << "请输入边的个数:";
    		cin >> num;
    		G.arcnums = num;
    		//依次输入各个顶点
    		cout << "依次输入各个顶点:" << endl;
    		for (int i = 0; i < G.vexnums; ++i)
    		{
    			int ch;
    			cin >> ch;
    			G.vexs.push_back(ch);
    		}
    		for (int i = 0; i < G.vexnums; ++i)//初始化各个边
    		{
    			vector<int> vec;
    			vec.clear();
    			for (int j = 0; j < G.vexnums; ++j)
    			{
    				vec.push_back(0);
    			}
    			G.arcs.push_back(vec);
    
    		}
    		cout << "依次输入两个关联的顶点:" << endl;
    		for (int i = 0; i < G.arcnums; ++i)
    		{
    			int vex1;
    			int vex2;
    			cin >> vex1 >> vex2;
    			G.arcs[vex1][vex2] = 1;
    			G.arcs[vex2][vex1] = 1;//
    			cout << "一条边构建成功!" << endl;
    		}
    		GetGraph(G);
    	}
    
    	//为了试验方便,我们自己创建一个固定的图
    	void CreatAGraph(AMGraph &G)
    	{
    		//创建顶点
    		G.vexnums = 6;
    		G.arcnums = 6;
    		for (int i = 0; i < G.vexnums; ++i)
    		{
    			G.vexs.push_back(i);
    		}
    		for (int i = 0; i < G.vexnums; ++i)//初始化各个边
    		{
    			vector<int> vec;
    			vec.clear();
    			for (int j = 0; j < G.vexnums; ++j)
    			{
    				vec.push_back(0);
    			}
    			G.arcs.push_back(vec);
    		}
    		G.arcs[0][1] = 6;
    		G.arcs[1][0] = 6;
    		G.arcs[0][2] = 1;
    		G.arcs[2][0] = 1;
    		G.arcs[0][3] = 5;
    		G.arcs[3][0] = 5;
    
    		G.arcs[1][2] = 5;
    		G.arcs[2][1] = 5;
    		G.arcs[1][4] = 3;
    		G.arcs[4][1] = 3;
    
    		G.arcs[2][4] = 6;
    		G.arcs[4][2] = 6;
    		G.arcs[2][5] = 4;
    		G.arcs[5][2] = 4;
    
    		G.arcs[3][2] = 5;
    		G.arcs[3][2] = 5;
    		G.arcs[3][5] = 2;
    		G.arcs[5][3] = 2;
    		
    
    		G.arcs[4][5] = 6;
    		G.arcs[5][4] = 6;
    
    		GetGraph(G);
    	}
    
    
    	vector<int> visited;//用来标注对应的节点是否被访问,如果被访问,则访问下一个节点
    	void DFSTraverse(AMGraph G)//深度优先遍历
    	{
    		visited.clear();
    		//初始化,假设每个节点都没有被访问
    		for (int i = 0; i < G.vexnums; ++i)
    		{
    			visited.push_back(0);//没访问的都设置为0,访问过的都设置为1
    		}
    		for (int v = 0; v < G.vexnums; ++v)
    		{
    			if (visited[v] == 0)//保证节点没有被访问
    				DFS(G, v);
    		}
    		cout << endl;
    	}
    	void DFS(AMGraph G, int v) //对i节点进行深度优先遍历
    	{
    		cout << "v_" << v << "  ";
    		visited[v] = 1;
    		for (int i = 0; i < G.vexnums; ++i)
    		{
    			if (G.arcs[v][i] != 0 && visited[i] == 0)//存在边,且i节点没有访问过
    				DFS(G, i);
    		}
    		return;
    	}
    
    	void  BFSTraverse(AMGraph G)//广度优先遍历
    	{
    		visited.clear();
    		for (int i = 0; i < G.vexnums; ++i)
    		{
    			visited.push_back(0);//没访问的都设置为0,访问过的都设置为1
    		}
    		for (int v = 0; v < G.vexnums; ++v)
    		{
    			if (visited[v] == 0 )
    			{
    				cout << "v_" << v << "  ";//节点没有被访问
    				visited[v] = 1;
    			}
    			for (int i = 0; i < G.vexnums; ++i)
    			{
    				if (visited[i] == 0 && G.arcs[v][i] != 0)
    				{
    					cout << "v_" << i << "  ";//节点没有被访问
    					visited[i] = 1;
    				}
    			}
    		}
    		cout << endl;
    	}
    	void BFS(AMGraph G, int v)
    	{
    		if (visited[v] == 0)
    		{
    			cout << "v_" << v << "  ";//节点没有被访问
    			visited[v] = 1;
    		}
    
    		for (int i = 0; i < G.vexnums; ++i)
    		{
    			if (visited[i] == 0)
    			{
    				cout << "v_" << v << "  ";//节点没有被访问
    				visited[v] = 1;
    			}
    		}
    	}
    
    	void  GetGraph(AMGraph G)
    	{
    		cout << "顶点信息:" << endl;
    		for (int i = 0; i < G.vexnums; ++i)
    		{
    			cout << G.vexs[i] << "  ";
    		}
    		cout << endl;
    		cout << "边的信息:" << endl;
    		for (int i = 0; i < G.vexnums; ++i)
    		{
    			for (int j = 0; j < G.vexnums; ++j)
    			{
    				cout << G.arcs[i][j] << "  ";
    			}
    			cout << endl;
    		}
    	}
    	//用普利姆算法构建最小生成树,最小生成树存在返回T
    	vector<int>nodes;//存储已经存在在U集合里面的点,每次从剩下的节点选择离nodes集合里面距离最小的节点
    vector<int>renodes;//存储剩余的节点
    
    	AMGraph  MinSpanTree_Prim(AMGraph G)
    	{
    		
    		AMGraph T;
    		T.vexnums = G.vexnums;
    		//初始化顶点
    		for (int i = 0; i < T.vexnums; ++i)
    		{
    			T.vexs.push_back(i);
    		}
    		//初始化边
    		for (int i = 0; i < T.vexnums; ++i)
    		{
    			renodes.push_back(i);//向renodes中插入节点
    			vector<int> vec;
    			
    			for (int j = 0; j < T.vexnums; ++j)
    			{
    			//	T.arcs[i][j] = 0;   //初始化T
    			
    				vec.push_back(0);
    			}
    			T.arcs.push_back(vec);
    		}
    		
    		//从v_0开始选边
    		nodes.push_back(0);//第0个边给node节点
    		renodes.erase(renodes.begin()+0);
    
    	
    		while (nodes.size()!=T.vexnums)
    		{
    			int minDistance = G.arcs[nodes[0]][renodes[0]];//记录最小距离
    		
    			int minNode1 = nodes[0];
    			int minNode2 = renodes[0];//记录离最小距离的节点
    			int flag = 0;//renodes中要删除的节点
    			bool visist = false;
    			int i = 0, j = 0;
    			for ( i = 0; i < nodes.size(); ++i)//选择距离最小的边
    			{
    				for ( j = 0; j < renodes.size(); ++j)
    				{
    					//找到最小距离,且最小距离和原来节点不形成回路
    					//if (visist == false && minDistance==0 && G.arcs[nodes[i]][renodes[j]] != 0 ) //距离不等于0 //只执行一次,找到最短距离
    					if ( minDistance == 0 && G.arcs[nodes[i]][renodes[j]] != 0) //距离不等于0 //只执行一次,找到最短距离
    					{
    						minDistance = G.arcs[nodes[i]][renodes[j]];
    						minNode1 = nodes[i];
    						minNode2 = renodes[j];
    						flag = j;
    					//	visist = true;  //visit保证这条语句只访问一次
    					//	cout << "flag:" << flag << endl;
    					}
    					if (G.arcs[nodes[i]][renodes[j]] != 0 && minDistance > G.arcs[nodes[i]][renodes[j]])
    					{
    						minDistance = G.arcs[nodes[i]][renodes[j]];
    					minNode1 = nodes[i];
    						minNode2 = renodes[j];
    						flag = j;
    					//	cout << "flag:" << flag << endl;
    					}
    					
    				}
    			//	cout << "最短距离是:" << minDistance << endl;
    			}
    			
    			T.arcs[minNode1][minNode2] = minDistance;
    			T.arcs[minNode2][minNode1] = minDistance;
    			T.arcnums++;
    			nodes.push_back(minNode2);
    			//cout << "flag:" << flag << endl;
    			cout << "nodes:" ;
    			print(nodes);
    			cout << endl;
    			
    			renodes.erase(renodes.begin()+flag);
    			//cout << "renodes:";
    			//print(renodes);
    			//cout << endl;
    			//cout << endl;
    			//cout << "T.vexnums:" << T.vexnums;
    			//cout << "nodes.size():" << nodes.size();
    		}
    		return T;
    	}
    	void print(vector<int> vec)
    	{
    		for (int i = 0; i < vec.size(); ++i)
    			cout << vec[i] << "  ";
    	}
    	//用克鲁斯算法构建最小生成树,最小生成树返回T
    	/*AMGraph MinSpanTree_Kruskal(AMGraph G)
    	{
    
    	}*/
    };
    int main()
    {
    
    
    	Solution so;
    
    	AMGraph G;
    	//so.CreateGraph(G);
    	so.CreatAGraph(G);
    	cout << "G深度优先遍历:" << endl;
    	so.DFSTraverse(G);
    
    	cout << "G广度优先遍历:" << endl;
    	so.BFSTraverse(G);
    	//so.GetGraph(G);
    
    	AMGraph T;
    	T = so.MinSpanTree_Prim(G);
    	cout << "T深度优先遍历:" << endl;
    	so.DFSTraverse(T);
    	cout << "T的信息:" << endl;
    	so.GetGraph(T);
    
    	return 0;
    }
  • 相关阅读:
    Ubuntu安装搜狗输入法
    Ubuntu 命令
    ubuntu忽然不能登录,输入密码正确一直返回登录界面
    chmod用法
    Maven学习(六)maven使用中遇到的坑
    win10下装mysql-5.7.18-winx64
    Maven学习(五)使用Maven构建多模块项目
    Maven学习(四)eclipse创建maven项目
    Maven学习(三)maven原理概念详述
    Struts2+Hibernate4+Spring4框架整合搭建Java项目原型
  • 原文地址:https://www.cnblogs.com/wdan2016/p/6183844.html
Copyright © 2020-2023  润新知