图的实现 邻接矩阵+无向图

来源:互联网 发布:数据库工程师证书 编辑:程序博客网 时间: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;}
原创粉丝点击