是的,今天又来啦~
终于迎来了数据结构之图篇一,这篇博客主要实现是图的邻接矩阵存储结构实现深度优先遍历和广度优先遍历。
首先呢?介绍一下
图的存储结构:1、邻接矩阵;2、邻接表; 3、十字链表; 4、邻接多重表
图的遍历方式:1、深度优先遍历; 2、广度优先遍历
最小生成树实现:1、普利姆算法; 2、克鲁斯尔算法
接着看代码
1、Node.h
#ifndef NODE_H
#define NODE_H
class Node
{
public:
Node(char data = 0);
char m_cData;
bool m_bIsVisited;
};
#endif
2、Node.cpp
#include "Node.h"
Node::Node(char data)
{
m_cData = data;
m_bIsVisited = false;
}
3、CMap.h
#include <vector>
#include "Node.h"
#include <iostream>
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 setValueToMatrixForUndirectedGraph(int row, int col, int val = 1); //无向图设置邻接矩阵
void printMatrix(); //打印邻接矩阵
void depthFirstTraverse(int nodeIndex); //深度优先遍历
void breadthFirstTraverse(int nodeIndex); //广度优先遍历
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; //存放邻接矩阵
};
4、CMap.cpp
#include "CMap.h"
#include <iostream>
using namespace std;
#include <vector>
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));
for (int i = 0; i < m_iCapacity * m_iCapacity; i++)
{
m_pMatrix[i] = 0;
}
}
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)
{
return false;
}
if (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)
{
return false;
}
if (col < 0 || col >= m_iCapacity)
{
return false;
}
m_pMatrix[row * m_iCapacity + col] = val;
m_pMatrix[col * m_iCapacity + row] = val;
return true;
}
bool CMap::getValueFromMatrix(int row, int col, int &val)
{
if(row < 0 || row >= m_iCapacity)
{
return false;
}
if (col < 0 || col >= m_iCapacity)
{
return false;
}
val = m_pMatrix[row * m_iCapacity + col];
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 == 1) //判断有弧连接其他顶点
{
//再判断该店是否被访问过
if (m_pNodeArray[i].m_bIsVisited)
{
continue;
}
else
{
depthFirstTraverse(i);
}
}
else
{
continue;
}
}
}
//广度优先遍历
void CMap::breadthFirstTraverse(int nodeIndex)
{
cout << m_pNodeArray[nodeIndex].m_cData << " ";
m_pNodeArray[nodeIndex].m_bIsVisited = true;
vector<int> curVec;
curVec.push_back(nodeIndex);
breadthFirstTraverseImpl(curVec);
}
void CMap::breadthFirstTraverseImpl(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)
{
continue;
}
else
{
cout << m_pNodeArray[i].m_cData << " ";
m_pNodeArray[i].m_bIsVisited = true;
curVec.push_back(i);
}
}
}
}
if (curVec.size() == 0)
{
return;
}
else
{
breadthFirstTraverseImpl(curVec);
}
}
5、CMapDemo.cpp
#include <iostream>
#include "CMap.h"
#include "Node.h"
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
/*
A
/ \
B D
/\ / \
C F G - H
\/
E
*/
int main(int argc, char** argv)
{
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(3, 6);
pMap->setValueToMatrixForUndirectedGraph(3, 7);
pMap->setValueToMatrixForUndirectedGraph(6, 7);
pMap->setValueToMatrixForUndirectedGraph(2, 4);
pMap->setValueToMatrixForUndirectedGraph(4, 5);
pMap->printMatrix();
cout << endl;
cout << "深度优先遍历:";
pMap->depthFirstTraverse(0);
cout << endl;
pMap->resetNode();
cout << "广度优先遍历:" ;
pMap->breadthFirstTraverse(0);
return 0;
}