C/C++ 图的基本操作

数据结构—图的基本操作:添加节点、为有向图/无向图添加邻接矩阵、打印邻接矩阵、深度优先遍历、广度优先遍历等。

1.demo.h主函数

1.demo.cpp
#include <iostream>
#include "CMap.h"
using namespace std;

/************************************/
/*无向图节点间权值都为1:
          A
        /   \
       B     D
      / \   / \
     C   F  G - H
     \  /
       E
A(0)    B(1)    C(2)    D(3)    
E(4)    F(5)    G(6)    H(7)
*/
/************************************/
int main(void)
{
    CMap *pMap = new CMap(8);//实例化对象

    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);

    pMap->setValueToMatrixForUndirectedGraph(0,1);//无向图 权值
    pMap->setValueToMatrixForUndirectedGraph(0,3);
    pMap->setValueToMatrixForUndirectedGraph(1,2);
    pMap->setValueToMatrixForUndirectedGraph(1,5);
    pMap->setValueToMatrixForUndirectedGraph(2,4);
    pMap->setValueToMatrixForUndirectedGraph(3,6);
    pMap->setValueToMatrixForUndirectedGraph(3,7);
    pMap->setValueToMatrixForUndirectedGraph(4,5);
    pMap->setValueToMatrixForUndirectedGraph(6,7);

    cout<<"邻接矩阵:"<<endl;
    pMap->printMatrix();
    cout<<endl;

    cout<<"深度优先遍历:"<<endl;
    pMap->depthFirstTraverse(0);//深度优先遍历
    cout<<endl;

    pMap->resetNode();//重置 都没有访问过状态

    cout<<"广度优先遍历:"<<endl;
    pMap->breadthFirstTraverse(0);//广度优先遍历
    cout<<endl;

    //delete []pMap;
    //pMap = NULL;
    system("pause");
    return 0;
}

2.图的.h类文件

2. CMap.h
#ifndef CMAP_H
#define CMAP_H
#include 
using namespace std;
#include "Node.h"
class CMap
{
public:
    CMap(int capacity);
    ~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);       //广度优先遍历 2部分

private:
    bool getValueFromMatrix(int row, int col, int &val);    //从矩阵中获取权值
    void breadthFirstTraverseImpl(vector<int> preVec);      //广度优先遍历实现函数

private:
    int m_iCapacity;    //图中最多可容纳的顶点数
    int m_iNodeCount;   //已经添加的顶点个数
    Node *m_pNodeArray; //用来存放顶点数组
    int *m_pMatrix;     //用来存放邻接矩阵  这里用的一维数组
};

#endif // !CMAP_H

3.图类的.cpp实现文件

3. CMap.cpp
#include "CMap.h"
#include 
using namespace std;
CMap::CMap(int capacity)
{
    m_iCapacity = capacity;
    m_iNodeCount = 0;
    m_pNodeArray = new Node[m_iCapacity];
    m_pMatrix = new int[m_iCapacity*m_iCapacity];
    memset(m_pMatrix, 0, sizeof(int)*m_iCapacity*m_iCapacity);
}
CMap::~CMap()
{
    delete []m_pNodeArray;
    delete []m_pMatrix;
}
//向图中加入节点
bool CMap::addNode(Node *pNode)
{
    if (pNode == NULL)
    {
        return false;
    }
    m_pNodeArray[m_iNodeCount].m_cData = pNode->m_cData;
    m_iNodeCount++;
    return true;
}
//重置顶点   都设置为没有访问过
void  CMap::resetNode()
{
    for (int i = 0; i < m_iNodeCount; i++)
    {
        m_pNodeArray[i].m_bIsVisited = false;
    }
}
//为有向图设置邻接矩阵
bool  CMap::setValueToMatrixForDirectedGraph(int row, int col, int val)
{
    if (row < 0 || row >= m_iCapacity || col < 0 || col >= m_iCapacity)
    {
        return false;
    }
    m_pMatrix[row*m_iCapacity + col] = val;//单向
    return true;
}
//为无向图设置邻接矩阵
bool  CMap::setValueToMatrixForUndirectedGraph(int row, int col, int val)
{
    if (row < 0 || row >= m_iCapacity || col < 0 || col >= m_iCapacity)
    {
        return false;
    }
    m_pMatrix[row*m_iCapacity + col] = val;
    m_pMatrix[col*m_iCapacity + row] = val;//双向
    return true;
}
//打印邻接矩阵
void  CMap::printMatrix()
{
    for (int i = 0; i < m_iCapacity; i++)
    {
        for (int k = 0; k < m_iCapacity; k++)
        {
            cout<" ";
        }
        cout<//深度优先遍历
void  CMap::depthFirstTraverse(int nodeIndex)
{
    int value = 0;
    cout<" ";
    m_pNodeArray[nodeIndex].m_bIsVisited = true;
    for (int i = 0; i < m_iCapacity; i++)
    {
        getValueFromMatrix(nodeIndex, i, value);//得到权值
        if (value != 0)//两点间有连接
        {
            if (m_pNodeArray[i].m_bIsVisited)//是否访问过
            {
                continue;
            }
            else
            {
                depthFirstTraverse(i);//递归
            }
        }
        else
        {
            continue;
        }
    }
}

//从矩阵中获取权值
bool  CMap::getValueFromMatrix(int row, int col, int &val)
{
    if (row < 0 || row >= m_iCapacity || col < 0 || col >= m_iCapacity)
    {
        return false;
    }
    val = m_pMatrix[row*m_iCapacity + col];
    return true;
}

//广度优先遍历  比深度复杂些   一层放一个数组,按照数组里面存放的数据再次访问
void  CMap::breadthFirstTraverse(int nodeIndex)
{
    vector<int> curVec;
    cout<" ";
    m_pNodeArray[nodeIndex].m_bIsVisited = true;

    curVec.push_back(nodeIndex);
    breadthFirstTraverseImpl(curVec);
}

//广度优先遍历实现函数
void  CMap::breadthFirstTraverseImpl(vector<int> preVec)
{
    int value = 0;
    vector<int> curVec;

    for (int i = 0; i < (int)preVec.size(); i++)
    {
        //当前节点所有相连的,就是一层一层的
        for (int j = 0; j < m_iCapacity; j++)
        {
            getValueFromMatrix(preVec[i], j, value);
            if (value != 0)
            {
                if (m_pNodeArray[j].m_bIsVisited)
                {
                    continue;
                }
                else
                {
                    cout<" ";
                    m_pNodeArray[j].m_bIsVisited = true;

                    curVec.push_back(j);
                }
            }
            else
            {
                continue;
            }
        }
    }
    //preVec层的所有下一层curVec已经被找到,再次递归找这层的
    if (curVec.size() != 0)
    {
        breadthFirstTraverseImpl(curVec);
    }
    else
    {
        return;
    }
}       

4.图中节点的.h类文件

4. Node.h
#ifndef NODE_H
#define NODE_H

class Node
{
public:
    Node(char data = 0);
    char m_cData;   //数据
    bool m_bIsVisited;//是否被访问的标识

};
#endif // !NODE_H

5.节点Node.cpp文件

5. Node.cpp
#include "Node.h"

Node::Node(char data)
{
    m_cData = data;
    m_bIsVisited = false;
}

结果:
C/C++ 图的基本操作_第1张图片

你可能感兴趣的:(C++学习之路(MOOC))