图的实现 邻接矩阵+无向图
来源:互联网 发布:数据库工程师证书 编辑:程序博客网 时间:2024/05/22 16:06
#include <iostream>#include <string.h>#include <vector>#include <stdlib.h>using namespace std;class Node{public: Node(char data = 0);//构造函数 初始化 char m_Data; //值 bool m_blsVisited; //标识是否被访问过 };class Edge{public: Edge(int nodeIndexA = 0, int nodeIndexB = 0, int weightValue = 0); int m_iNodeIndexA; int m_iNodeIndexB; int m_iWeightValue; bool m_bSelected; };class CMap{public: CMap(int iCapacity); ~CMap(); bool AddNode(Node* pNode); void ResetNode(); //对邻接矩阵的操作 bool SetValueToMatrixForDirectedGraph(int row, int col, int val = 1); bool SetValueToMatrixForUndirectedGraph(int row, int col, int val = 1); void PrintMatrix(); //遍历 void DepthFirstTraverse(int NodeIndex); void BreadthFirstTraverse(int NodeIndex); //最小生成树 void primTree(int nodeIndex); //nodeIndex指定的第一个点 void KruskalTree();private: bool GetValueFromMatrix(int row, int col, int &val); void BreadthFirstTraverseImpl(vector<int> preVec); int GetMinEdge(vector<Edge> EdgeVec); bool IsInSet(vector<int> nodeSet, int target); void MergeNodeSet(vector<int> &nodeSetA, vector<int> nodeSetB);private: int m_iCapacity; //途中最多可以容纳的顶点数 int m_iNodeCount; //已经添加的顶点个数 Node *m_pNodeArray; //用来存放顶点数组 int *m_pMatrix; //存放邻接矩阵 Edge *m_pEdge; //存最小生成树中的边 };Node::Node(char data) { m_Data = data; m_blsVisited = false;}CMap::CMap(int iCapacity){ m_iCapacity = iCapacity; m_iNodeCount = 0; m_pNodeArray = new Node[m_iCapacity]; m_pMatrix = new int [m_iCapacity*m_iCapacity]; memset(m_pMatrix, 0, m_iCapacity*m_iCapacity*sizeof(int)); m_pEdge = new Edge[iCapacity - 1]; }CMap::~CMap(){ delete [] m_pNodeArray; delete [] m_pMatrix; delete [] m_pEdge;}bool CMap::AddNode(Node* pNode){ m_pNodeArray[m_iNodeCount].m_Data = pNode->m_Data; m_iNodeCount++; return true;}void CMap::ResetNode(){ for(int i = 0; i < m_iNodeCount; i++) { m_pNodeArray[i].m_blsVisited = false; }}//有向图邻接矩阵 bool CMap::SetValueToMatrixForDirectedGraph(int row, int col, int val){ m_pMatrix[row*m_iCapacity + col] = val; return true; }bool CMap::SetValueToMatrixForUndirectedGraph(int row, int col, int val){ m_pMatrix[row*m_iCapacity + col] = val; m_pMatrix[col*m_iCapacity + row ]= val; return true;}bool CMap::GetValueFromMatrix(int row, int col, int &val){ val = m_pMatrix[row*m_iCapacity + col]; return true;}void CMap::PrintMatrix(){ for(int i = 0; i < m_iCapacity; i++) { for(int j = 0; j < m_iCapacity; j++) { cout << m_pMatrix[i*m_iCapacity + j] << " "; } cout << endl; }}void CMap::DepthFirstTraverse(int NodeIndex){ int value = 0; cout << m_pNodeArray[NodeIndex].m_Data << " "; m_pNodeArray[NodeIndex].m_blsVisited = true; for(int i =0; i < m_iCapacity; i++) { GetValueFromMatrix(NodeIndex, i, value); if(value == 1) { if(m_pNodeArray[i].m_blsVisited) { continue; } else { DepthFirstTraverse(i); } } else { continue; } }}void CMap::BreadthFirstTraverse(int NodeIndex){ cout << m_pNodeArray[NodeIndex].m_Data << " "; m_pNodeArray[NodeIndex].m_blsVisited = true; vector<int> curVec; curVec.push_back(NodeIndex); BreadthFirstTraverseImpl(curVec);}void CMap::BreadthFirstTraverseImpl(vector<int> preVec) { int value = 0; vector<int> curVec; //保存当前这一层所有节点 //preVec 上一层所有节点 for(int j = 0; j < (int)preVec.size(); j++) // { for(int i = 0; i < m_iCapacity; i++) //上一层 节点其中一个节点与其他节点是否有连接 { //在邻接矩阵中 查一查 传入进来的数组中的一个点是否与其他点 有连接 GetValueFromMatrix(preVec[j], i, value); if(value != 0) { if(m_pNodeArray[i].m_blsVisited) { continue; } else { cout << m_pNodeArray[i].m_Data << " "; m_pNodeArray[i].m_blsVisited = true; curVec.push_back(i); } } } } if(curVec.size() == 0) { return ; } else { BreadthFirstTraverseImpl(curVec); }}Edge::Edge(int nodeIndexA, int nodeIndexB, int weightValue){ m_iNodeIndexA = nodeIndexA; m_iNodeIndexB = nodeIndexB; m_iWeightValue = weightValue; m_bSelected = false;}//普利姆生成树 void CMap::primTree(int nodeIndex){ int value = 0; //取边的权值 int edgeCount = 0; vector<int> NodeVec; //存储点的集合 vector<Edge> EdgeVec; //备选边的集合 cout << m_pNodeArray[nodeIndex].m_Data << endl; m_pNodeArray[nodeIndex].m_blsVisited = true; NodeVec.push_back(nodeIndex); while(edgeCount < m_iCapacity - 1) { int temp = NodeVec.back(); //取出最尾部的元素 //将与temp节点所连的所有的边都放入备选边集合 for(int i = 0; i < m_iCapacity; i++) { GetValueFromMatrix(temp, i, value); if(value != 0) { if(m_pNodeArray[i].m_blsVisited) { continue; } else { Edge edge(temp, i, value); EdgeVec.push_back(edge); } } } //从备选边集合中找出最小的边 传出最小边的边索引 int edgeIndex = GetMinEdge(EdgeVec); EdgeVec[edgeIndex].m_bSelected = true; cout << EdgeVec[edgeIndex].m_iNodeIndexA << "......" << EdgeVec[edgeIndex].m_iNodeIndexB << " "; cout << EdgeVec[edgeIndex].m_iWeightValue << endl; m_pEdge[edgeCount++] = EdgeVec[edgeIndex]; //找到与当前最小边所连接的点 int nextNodeIndex= EdgeVec[edgeIndex].m_iNodeIndexB; NodeVec.push_back(nextNodeIndex); m_pNodeArray[nextNodeIndex].m_blsVisited = true; cout << m_pNodeArray[nextNodeIndex].m_Data << endl; }}int CMap::GetMinEdge(vector<Edge> EdgeVec){ int minWeight = 0; int edgeIndex = 0; int i= 0; //取出第一条未访问的边 for(; i < EdgeVec.size(); i++) { if(!EdgeVec[i].m_bSelected) { minWeight = EdgeVec[i].m_iWeightValue; edgeIndex = i; break; } } if(minWeight == 0) { return -1; } //剩余边中找最小边 for(; i < EdgeVec.size(); i++) { if(!EdgeVec[i].m_bSelected) { if(minWeight > EdgeVec[i].m_iWeightValue) { minWeight = EdgeVec[i].m_iWeightValue; edgeIndex = i; } } else { continue ; } } return edgeIndex;}bool CMap::IsInSet(vector<int> nodeSet, int target){ for(int i = 0; i < nodeSet.size(); i++) { if(nodeSet[i] == target) { return true; } } return false; } void CMap::MergeNodeSet(vector<int> &nodeSetA, vector<int> nodeSetB){ for(int i = 0; i < nodeSetB.size(); i++) { nodeSetA.push_back(nodeSetB[i]); }}void CMap::KruskalTree(){ int value = 0; int edgeCount = 0; //定义一个点集合的数组 vector< vector<int> > NodeSets; //1.取出所有的边 vector<Edge> EdgeVec; for(int i = 0; i < m_iCapacity; i++) { for(int j = i + 1; j < m_iCapacity; j++) //取出邻接矩阵上半个三角,不含主对角线上的数据 { GetValueFromMatrix(i, j, value); if(value != 0) { Edge edge(i, j, value); EdgeVec.push_back(edge); } } } //2. 从所有边中取出组成最小生成树的边 // 找到算法结束条件 边数 = 顶点数 - 1 while(edgeCount < m_iCapacity - 1) { // 从边集合中找到最小边 int minEdgeIndex = GetMinEdge(EdgeVec); EdgeVec[minEdgeIndex].m_bSelected = true; //找到最小边连接的点 int nodeAIndex = EdgeVec[minEdgeIndex].m_iNodeIndexA; int nodeBIndex = EdgeVec[minEdgeIndex].m_iNodeIndexB; bool nodeAIsInSet = false; bool nodeBIsInSet = false; int nodeAInSetLabel = -1; int nodeBInSetLabel = -1; //找出A点所在的集合 for(int i = 0; i < NodeSets.size(); i++) { nodeAIsInSet = IsInSet(NodeSets[i], nodeAIndex); if(nodeAIsInSet) { nodeAInSetLabel = i; } } //找出B点所在的集合 for(int i = 0; i < NodeSets.size(); i++) { nodeBIsInSet = IsInSet(NodeSets[i], nodeAIndex); if(nodeBIsInSet) { nodeBInSetLabel = i; } } //根据点所在的集合做出不同的处理 if(nodeAInSetLabel == -1 && nodeBInSetLabel == -1) { vector<int> vec; vec.push_back(nodeAInSetLabel); vec.push_back(nodeBInSetLabel); NodeSets.push_back(vec); } else if(nodeAInSetLabel == -1 && nodeBInSetLabel != -1) { NodeSets[nodeBInSetLabel].push_back(nodeAInSetLabel); } else if(nodeAInSetLabel != -1 && nodeBInSetLabel == -1) { NodeSets[nodeAInSetLabel].push_back(nodeBInSetLabel); } else if(nodeAInSetLabel != -1 && nodeBInSetLabel != -1 && nodeAInSetLabel != nodeBInSetLabel) { MergeNodeSet(NodeSets[nodeAInSetLabel], NodeSets[nodeBInSetLabel]);//合并集合 for(int k = nodeBInSetLabel; k < (int)NodeSets.size() - 1; k++) //类似于在队列中删除一个节点 { NodeSets[k] = NodeSets[k + 1]; } } else if(nodeAInSetLabel != -1 && nodeBInSetLabel != -1 && nodeAInSetLabel == nodeBInSetLabel) { continue ; } m_pEdge[edgeCount++] = EdgeVec[minEdgeIndex]; cout << EdgeVec[minEdgeIndex].m_iNodeIndexA << "......" << EdgeVec[minEdgeIndex].m_iNodeIndexB << " "; cout << EdgeVec[minEdgeIndex].m_iWeightValue << endl; }}int main(){ CMap *pMap = new CMap(6); Node *pNodeA = new Node('A'); Node *pNodeB = new Node('B'); Node *pNodeC = new Node('C'); Node *pNodeD = new Node('D'); Node *pNodeE = new Node('E'); Node *pNodeF = new Node('F');// Node *pNodeG = new Node('G');// Node *pNodeH = new Node('H'); pMap->AddNode(pNodeA); pMap->AddNode(pNodeB); pMap->AddNode(pNodeC); pMap->AddNode(pNodeD); pMap->AddNode(pNodeE); pMap->AddNode(pNodeF);// pMap->AddNode(pNodeG);// pMap->AddNode(pNodeH);#if 0 pMap->SetValueToMatrixForUndirectedGraph(0, 1); pMap->SetValueToMatrixForUndirectedGraph(0, 3); pMap->SetValueToMatrixForUndirectedGraph(1, 2); pMap->SetValueToMatrixForUndirectedGraph(1, 5); pMap->SetValueToMatrixForUndirectedGraph(3, 6); pMap->SetValueToMatrixForUndirectedGraph(3, 7); pMap->SetValueToMatrixForUndirectedGraph(6, 7); pMap->SetValueToMatrixForUndirectedGraph(2, 4); pMap->SetValueToMatrixForUndirectedGraph(4, 5);#endif pMap->SetValueToMatrixForUndirectedGraph(0, 1, 6); pMap->SetValueToMatrixForUndirectedGraph(0, 4, 5); pMap->SetValueToMatrixForUndirectedGraph(0, 5, 1); pMap->SetValueToMatrixForUndirectedGraph(1, 2, 3); pMap->SetValueToMatrixForUndirectedGraph(1, 5, 2); pMap->SetValueToMatrixForUndirectedGraph(2, 5, 8); pMap->SetValueToMatrixForUndirectedGraph(2, 3, 7); pMap->SetValueToMatrixForUndirectedGraph(3, 5, 4); pMap->SetValueToMatrixForUndirectedGraph(3, 4, 2); pMap->SetValueToMatrixForUndirectedGraph(4, 5, 9); pMap->PrintMatrix(); cout << endl;#if 0 pMap->ResetNode(); pMap->DepthFirstTraverse(0); cout << endl; pMap->ResetNode(); pMap->BreadthFirstTraverse(0); cout << endl;#endif pMap->KruskalTree(); system("pause"); return 0;}
阅读全文
0 0
- 图的实现 邻接矩阵+无向图
- 邻接矩阵实现无向图的创建
- 邻接矩阵实现的无向图
- 无向图的邻接矩阵
- 邻接矩阵(有向图,无向图实现的差异)
- 无向图邻接矩阵
- 邻接矩阵无向图
- 邻接矩阵--无向图
- Java实现无向无权图的邻接矩阵的存储
- 无向图的广度优先遍历---邻接矩阵实现
- 无向图的邻接矩阵基本操作
- 无向图的邻接矩阵创建表示
- 邻接矩阵存储带权值的无向图
- 无向图的邻接矩阵存储
- C++邻接矩阵实现有向图、无向图
- 邻接矩阵(无向图)
- Python 邻接矩阵实现无向图、有向图的三种方法,并绘图显示
- 数据结构之用邻接矩阵实现赋值无向图,有向图,无向图
- 微信小程序客服消息按钮太小解决方法contact-button
- PHP中的MYSQL常用函数总结
- 一些关于Python的小心得
- 《深入理解Linux内核》软中断/tasklet/工作队列
- Python中的调试(assert, logging, pdb, pdb.set_trace(), IDE)
- 图的实现 邻接矩阵+无向图
- ArrayList、LinkedList和HashSet、TreeSet以及HashMap、TreeMap是如何实现存储的?
- 中石油 2017暑假 拯救小鸡
- Android_适配器的使用
- android代码混淆
- 动态替换Linux核心函数的原理和实现
- Java 8十个lambda表达式案例
- C语言学习
- 聚类入门学习总结一