1. 程式人生 > >C/C++ 圖的基本操作

C/C++ 圖的基本操作

資料結構—圖的基本操作:新增節點、為有向圖/無向圖新增鄰接矩陣、列印鄰接矩陣、深度優先遍歷、廣度優先遍歷等。

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

結果:
這裡寫圖片描述