数据结构 - 图的基本操作 深度和广度遍历

##代码实现
###main.cpp(主函数)

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

/**
图的的存储:邻接矩阵
图的遍历:深度+广度


         A
      /    \
     B      D
    / \    /  \
   C    F G  - H
    \  /
     E
//
深度优先遍历: ABCEFDGH
广度优先遍历: ABDCDGHE
//横链接纵
实际数组 ABCDEFGH
邻接矩阵
  A B C D E F G H
A   1   1
B 1   1     1
C   1     1
D 1           1 1
E     1     1
F   1     1
G       1        1
H       1     1

**/
int main()
{
    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->setValueToMatrixForUndiretedGraph(0,1);
    pMap->setValueToMatrixForUndiretedGraph(0,3);
    pMap->setValueToMatrixForUndiretedGraph(1,2);
    pMap->setValueToMatrixForUndiretedGraph(1,5);
    pMap->setValueToMatrixForUndiretedGraph(3,6);
    pMap->setValueToMatrixForUndiretedGraph(3,7);
    pMap->setValueToMatrixForUndiretedGraph(2,4);
    pMap->setValueToMatrixForUndiretedGraph(5,4);
    pMap->setValueToMatrixForUndiretedGraph(6,7);

    pMap->printMatrix();

    cout<<endl;

    pMap->depthFirstTraverse(0);
    pMap->resetNode();
    cout<<endl;

    pMap->breathFirstTraverse(0);




   // cout << "Hello world!" << endl;



    return 0;
}

###Node.h(节点头文件)

#ifndef NODE_H
#define NODE_H
class Node{
public:
    Node(char data=0);
    char m_cData;  //数据值
    bool m_bIsVisited;  //有无被访问记录
};

#endif // NODE_J

###Node.cpp(节点源文件)

#include "Node.h"

Node::Node(char data)
{

    m_cData=data;
    m_bIsVisited=false;
}

###CMap.h(图头文件)

#ifndef CMAP_H
#define CMAP_H
#include "Node.h"
#include <vector>
using namespace std;
class CMap
{
public:
    CMap(int capacity); //构造函数
    ~CMap(); //析构函数
    bool addNode(Node *pNode); //向图中加入顶点(结点)
    void resetNode();  //重置顶点
    bool setValueToMatrixForDirectedGraph(int row,int col,int val=1);  //为有向图设置邻接矩阵
    bool setValueToMatrixForUndiretedGraph(int row,int col,int val=1);  //为无向图设置邻接矩阵
    void printMatrix(); //打印邻接矩阵
    void depthFirstTraverse(int nodeIndex);//深度优先遍历
    void breathFirstTraverse(int nodeIndex); //广度优先便利
    /*数据成员*/
private:
    int m_iCapacity; //图中最多可以容纳的顶点数
    int m_iNodeCount;  //已经添加的顶点(结点)个数
    Node *m_pNodeArray; //用来存放数组
    int *m_pMatrix;  //用来存放矩阵 表示结点的相应关系和权值
    void breathFirstTraverseImpl(vector<int> preVec); //从广度优先实现
    bool getValueFromMatrix(int row,int col,int &val);  //从矩阵中获取数值
};
#endif // CMAP_H

###CMap.cpp(图源文件)

#include "CMap.h"
#include <iostream>
#include <cstring>
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,m_iCapacity*m_iCapacity*sizeof(int));  //对邻接矩阵进行初始化
    /*也可以通过循环赋值初始化*/

}
CMap::~CMap()
{

    delete []m_pMatrix;
    delete []m_pNodeArray;
}
bool CMap::addNode(Node *pNode)
{
    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)
        return false;
    if(col<0&&col>=m_iCapacity)
        return false;
    m_pMatrix[row*m_iCapacity+col]=1;              //以正方向(行开始)
    return false;
}
bool CMap::setValueToMatrixForUndiretedGraph(int row,int col,int val)
{
    if(row<0&&row>=m_iCapacity)
        return false;
    if(col<0&&col>=m_iCapacity)
        return false;

    m_pMatrix[row*m_iCapacity+col]=1;              //以正方向(行开始)
    m_pMatrix[col*m_iCapacity+row]=1;               //反方向
    return false;
}
void CMap::printMatrix()
{
    for(int i=0; i<m_iCapacity; i++)
    {

        for(int k=0; k<m_iCapacity; k++)
        {

            cout<<m_pMatrix[i*m_iCapacity+k]<<" ";
        }
        cout<<endl;
    }

}

bool CMap::getValueFromMatrix(int row,int col,int &val)  //获取权值为0不相连  使用引用来传递值
{
    val=m_pMatrix[row*m_iCapacity+col];
    return true;
}


//深度优先遍历
void CMap::depthFirstTraverse(int nodeIndex)
{

    int value=0;
    cout<<m_pNodeArray[nodeIndex].m_cData<<" ";
    m_pNodeArray[nodeIndex].m_bIsVisited=true;
    //表示已访问
    //从邻接矩阵中查找与i相连接的节点
    for(int i=0; i<m_iCapacity; i++)
    {

        getValueFromMatrix(nodeIndex,i,value);
        //是否存在这条弧
        if(value==1)
        {
            if(m_pNodeArray[i].m_bIsVisited==true)
                continue;
            else
            {
                depthFirstTraverse(i); //对当前进行递归 继续深度优先去搜索
            }

        }
        else
        {
            continue;
        }
    }
}
/**


         A
      /    \
     B      D
    / \    /  \
   C    F G  - H
    \  /
     E



**/

//广度优先便利
void CMap::breathFirstTraverse(int nodeIndex)
{
    cout<<m_pNodeArray[nodeIndex].m_cData<<" ";
    m_pNodeArray[nodeIndex].m_bIsVisited=true;
    vector<int> curVec;
    curVec.push_back(nodeIndex);  //保存数值到一个新的数组中
    breathFirstTraverseImpl(curVec);
}

void CMap::breathFirstTraverseImpl(vector<int> preVec)
{
    int value=0;
    vector<int> curVec;

    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_bIsVisited==true)  //已经被访问过 则跳过
                {
                    continue;
                }
                else
                {
                    cout<<m_pNodeArray[i].m_cData<<" "; //输出下一层元素的数值
                    m_pNodeArray[i].m_bIsVisited=true;
                    curVec.push_back(i);  //将下一层数值的索引放入迭代器中以便继续进行查找
                }

            }
        }
    }

    if(curVec.size()==0)
    {
        return; //本层无点
    }
    else
    {
        breathFirstTraverseImpl(curVec); //有点,继续进行广度优先搜索
    }
}

使用的编译器: CodeBlocks13.12 with GCC compiler
资料来源: 慕课网 immc.com

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/weclove2008/article/details/77923228
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞