資料結構之圖篇(2):圖的基本操作 深度和廣度遍歷
阿新 • • 發佈:2018-12-05
程式碼實現
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