1. 程式人生 > >資料結構之圖篇(2):圖的基本操作 深度和廣度遍歷

資料結構之圖篇(2):圖的基本操作 深度和廣度遍歷

程式碼實現

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