C/C++ 圖的基本操作
阿新 • • 發佈:2019-01-06
資料結構—圖的基本操作:新增節點、為有向圖/無向圖新增鄰接矩陣、列印鄰接矩陣、深度優先遍歷、廣度優先遍歷等。
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 <vector>
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 <iostream>
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<<m_pMatrix[i*m_iCapacity+k]<<" ";
}
cout<<endl;
}
}
//深度優先遍歷
void CMap::depthFirstTraverse(int nodeIndex)
{
int value = 0;
cout<<m_pNodeArray[nodeIndex].m_cData<<" ";
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_cData<<" ";
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_cData<<" ";
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;
}
結果: