继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

C++模板化设计图的邻接矩阵表示法【Van0512】

慕姐3585284
关注TA
已关注
手记 10
粉丝 22
获赞 199

听完James老师的课,就想着把图的邻接矩阵表示法写成一个模板。
邻接矩阵适合表示稠密图,对于稀疏图,应该用链表实现才合算。
同时邻接矩阵的遍历的时间复杂度是O(n^2),而邻接表则是O(n + e)。
n表示顶点数量,e表示边数量。


对James老师的实现方式我做了一些修改。

  1. 由于要设置成模板,所以将表示顶点的类内置(in-class)。
  2. 对部分虽然通俗易懂但是略显冗余的代码做了精简。
  3. 广度优先我认为用队列实现更佳,重写了实现代码。
    要注意的是:
  4. 由于许多编译器不支持类模板的头文件与实现文件分离编译,所以把它们都放在头文件中。
  5. 在大数据遍历的过程中,局部变量造成的额外内存开销还是很客观的,因此,应当将参数列表都改成 const 的引用。为了便于阅读,这边我没有这样处理。
    下面是MyMap.h的实现代码:

#ifndef MYMAP_H
#define MYMAP_H

#include <iostream>
#include <queue>
#include <cstring>
using namespace std;

template <typename T>
class MyMap {
    public:
        MyMap(int capacity);
        ~MyMap();
        //添加的顶点对应的索引依次为0 ... capacity-1. 
        bool addVertex(T data);
        void resetVertex();
        //分别给有向图和无向图添加边。 
        bool setValue2Matrix4DirectedGraph(int row, int col, int val = 1);
        bool setValue2Matrix4UndirectedGraph(int row, int col, int val = 1);
        void DFS(int vertexIndex) const;    //depth first search. 
        void BFS(int vertexIndex) const;    //breadth first search.
    private:
        bool isAvailable(int row, int col) const;   //row, col合法性判断
        int getValueFromMatrix(int row, int col) const;

    private:
        struct Vertex { //默认访问权限 -> public 
            T data;
            bool isVisited;
        };
        int capacity;   //最多可容纳顶点数
        int cntV;       //已添加顶点数
        Vertex *arrV;   //顶点数组
        int *pMatrix;   //邻接矩阵 
};

template <typename T>
MyMap<T>::MyMap(int capacity) {
    this->capacity = capacity;
    cntV = 0;
    arrV = new Vertex[capacity];
    pMatrix = new int[capacity * capacity];
    memset(pMatrix, 0, capacity * capacity * sizeof(int));
}

template <typename T>
MyMap<T>::~MyMap() {
    delete[] arrV;
    delete[] pMatrix;
}

template <typename T>
bool MyMap<T>::addVertex(T data) {
    if(cntV == capacity) return false;
    arrV[cntV].data = data;
    arrV[cntV++].isVisited = false;
    return true;
}

template <typename T>
void MyMap<T>::resetVertex() {
    for(int i = 0; i < cntV; ++i) 
        arrV[i].isVisited = false;
}

template <typename T> 
bool MyMap<T>::setValue2Matrix4DirectedGraph(int row, int col, int val) {
    if(!isAvailable(row, col)) return false;
    pMatrix[row * capacity + col] = val;
    return true;
}

template <typename T>
bool MyMap<T>::setValue2Matrix4UndirectedGraph(int row, int col, int val) {
    if(!isAvailable(row, col)) return false;
    pMatrix[row * capacity + col] = pMatrix[col * capacity + row] = val;
    return true;
}

template <typename T>
void MyMap<T>::DFS(int vertexIndex) const {
    cout << arrV[vertexIndex].data << " ";
    arrV[vertexIndex].isVisited = true;
    for(int i = 0; i < cntV; ++i) {
        if(getValueFromMatrix(vertexIndex, i) > 0 && !arrV[i].isVisited)
            DFS(i);
    }
}

template <typename T>
void MyMap<T>::BFS(int vertexIndex) const {
    queue<int> que;
    que.push(vertexIndex);
    while(!que.empty()) {
        int index = que.front();
        que.pop();
        if(!arrV[index].isVisited) {
            cout << arrV[index].data << " ";
            arrV[index].isVisited = true;
        }

        for(int i = 0; i < cntV; ++i) {
            if(getValueFromMatrix(index, i) > 0 && !arrV[i].isVisited)
                que.push(i);
        } 
    }
}

template <typename T>
bool MyMap<T>::isAvailable(int row, int col) const {
    return 0 <= row && row < capacity && 0 <= col && col < capacity;
}

template <typename T>
int MyMap<T>::getValueFromMatrix(int row, int col) const {
    if(!isAvailable(row, col)) return -1;
    return pMatrix[row * capacity + col];
}

#endif

这是测试文件代码:


int main(void) {
    MyMap<char> myMap(8);
    for(char ch = 'a'; ch <= 'h'; ++ch)
        myMap.addVertex(ch);

    myMap.setValue2Matrix4UndirectedGraph(0, 1);
    myMap.setValue2Matrix4UndirectedGraph(0, 3);
    myMap.setValue2Matrix4UndirectedGraph(1, 2);
    myMap.setValue2Matrix4UndirectedGraph(1, 5);
    myMap.setValue2Matrix4UndirectedGraph(3, 6);
    myMap.setValue2Matrix4UndirectedGraph(3, 7);
    myMap.setValue2Matrix4UndirectedGraph(6, 7);
    myMap.setValue2Matrix4UndirectedGraph(2, 4);
    myMap.setValue2Matrix4UndirectedGraph(4, 5);

    myMap.resetVertex();
    cout << endl << "深度优先:";
    myMap.DFS(0);   //A B C E F D G H
    myMap.resetVertex();
    cout << endl << "广度优先:";
    myMap.BFS(0);   //A B D C F G H E
    cout << endl;

    return 0;
}
打开App,阅读手记
3人推荐
发表评论
随时随地看视频慕课网APP