数据结构之图---深度优先遍历---C++实现

来源:互联网 发布:js获取dom节点的方法 编辑:程序博客网 时间:2024/05/20 05:25
<span style="font-size:18px;"></span>

一、目标图对其实现深度优先遍历


下边的邻接矩阵是对上边无向图中结点与结点之间的连接关系,由于是无向图其邻接矩阵是关于对角线对称的。

二、实现深度优先遍历

1、结点的描述

结点除了有存储值的属性,还应该有点是否已被访问的属性

//Node.h#ifndef _NODE_H_#define _NODE_H_class Node{public:Node(char data = 0);char m_cData;bool m_bisVisited;};#endif

//Node.cpp#include "Node.h"Node::Node(char data){m_cData = data;m_bisVisited = false;}

2、图的描述

//CMap.h#ifndef _MY_MAP_H#define _MY_MAP_H#include "vector"#include "Node.h"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 breadthFirstTraversalImpl(vector<int> preVec);   //广度优先遍历实现函数private:int m_iCapacity;   //图中最多容纳的顶点数int m_iNodeCount;  //已经添加的顶点数Node *m_pNodeArray; //用来存放顶点的数组int *m_pMatrix;    //用来存放邻接矩阵};#endif

//CMap.cpp#include "CMap.h"#include <iostream>#include <vector>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));  //对邻接矩阵赋初值0/*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){   //设置有向图邻接矩阵,也是结点与结点之间的连接关系,1连通,0不连通if (row < 0 || row >= m_iCapacity){return false;}if (col < 0 || row >= m_iCapacity){return false;}m_pMatrix[row*m_iCapacity + col] = val;return true;}bool CMap::setValueToMatrixForUndirectedGraph(int row, int col, int val){ //无有向图邻接矩阵,也是结点与结点之间的连接关系,1连通,0不连通if (row < 0 || row >= m_iCapacity){return false;}if (col < 0 || row >= 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) //从邻接矩阵中获取权值,1表示连通,0未连通{if (row < 0 || row >= m_iCapacity){return false;}if (col < 0 || row >= 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;}}}


3、算法的调用

//main.cpp#include "stdio.h"#include "stdlib.h"#include "CMap.h"#include <iostream>/*图的存储和图的遍历*/using namespace std;void 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->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;//传0是为了选择一个起始位置(A),pMap->depthFirstTraverse(0);  }


三、深度优先遍历的算法分析

算法核心代码

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;}}}

算法思路(以目标图为例):以A点为出发点,打印A点的数据并将A的访问属性设置为true。然后进入邻接矩阵中,循环找与A点相连接的结点B,如果B被访问了,跳过B继续找与A点相连的结点D;如果未被访问,向下继续找与B相连接的结点C。。。依次类推,见图所示的步骤,注意递归的回退。










0 0
原创粉丝点击