数据结构——图

本文介绍了一种使用临接矩阵和临接表实现图数据结构的方法。通过具体的代码示例展示了如何创建图、添加顶点和边,并提供了测试案例。适用于需要理解和实现基本图算法的读者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里写图片描述
临接矩阵

#pragma once
#include<iostream>
#include<assert.h>
using namespace std;
// 临接矩阵
template<class V,class W,size_t N,bool IsDirector=false>//IsDirector标记是无向图还是有向图,默认无向图
class GraphMartix
{
public:
    GraphMartix()
    {}
    GraphMartix(V* vertix)
    {
        //此处不要用 memset进行初始化,它适合于内置类型
        for (size_t i = 0; i < N; ++i)
        {
            _vertix[i] = vertix[i];
        }
        for (size_t i = 0; i < N; ++i)
        {
            for (size_t j = 0; j < N; ++j)
            {
                _martix[i][j] = W();
            }
        }
    }
    //添加边,已知两个顶点,以及权值
    void AddEdge(const V& src,const V& dst,const W& w)
    {
        //先获取这两个点的位置
        int srcIndex=_GetVertexIndex(src);
        int desInndex=_GetVertexIndex(dst);
        _martix[srcIndex][desInndex] = w;
        //如果为无向图,则需要两个点互相都联通
        if (IsDirector==false)
        {
            _martix[desInndex][srcIndex] = w;
        }
    }
    int _GetVertexIndex(const V& tervex)
    {
        for (size_t i = 0; i < N; ++i)
        {
            if (_vertix[i] == tervex)
                return i;
        }
        //按照设想,程序不应该走到这一步;如果到这里,说明该点没有被找到
        //所以在此处我们采用防御式编程
        assert(false);
        return -1;

    }
protected:
    V _vertix[N];//顶点集
    W _martix[N][N];//边集
};
void testMartix()
{
    string add[] = {"school","house","park","market","hospital"};
    GraphMartix<string,int, sizeof(add)/sizeof(add[0])> ghm(add);
    ghm.AddEdge("school", "house",1000);
    ghm.AddEdge( "house", "park",200);
    ghm.AddEdge("market", "hospital",100);
    ghm.AddEdge("park","hospital",700);
    ghm.AddEdge("park", "market", 600);


}

临接矩阵

template<class W>
struct LinkEdge
{
    W _w;//权重
    int _src;//边上起始节点
    int _dst;//边上目标节点
    LinkEdge<W>* _next;
    //在这里如果单纯实现临接表的话其实没有必要存目标节点
    //是最小生成树的算法要用到dst节点
    LinkEdge(int src,int dst,const W& w)
        :_w(w)
        ,_src(src)
        ,_dst(dst)
        , _next(NULL)
    {}
};
template<class V, class W, size_t N, bool IsDirector = false>
class GraphLink
{
    typedef LinkEdge<W> Edge;
public:
    GraphLink()
    {}
    GraphLink(V* vertexs)
    {
        _vertexs.reserve(N);
        for (size_t i = 0; i < N; ++i)
        {
            _vertexs.push_back(vertexs[i]);
        }
        _LinkTable.resize(N, NULL);
    }
    void AddEdge(const V& src,const V& dst,const W& w)
    {
        int srcIndex = _GetVertexIndex(src);
        int dstIndex = _GetVertexIndex(dst);
        //头插法向数组中插入节点
        _AddEdge(srcIndex,dstIndex,w);
        if (IsDirector == false)
        {
            _AddEdge(dstIndex,srcIndex,w);
        }
    }
    int _GetVertexIndex(const V& vertex)
    {
        for (size_t i = 0; i < N; ++i)
        {
            if (_vertexs[i] ==vertex)
                return i;
        }
        assert(false);
        return -1;
    }
    void _AddEdge(int srcIndex,int dstIndex,const W& w)
    {
        Edge* edge = new Edge(srcIndex,dstIndex,w);
        //头插
        edge->_next = _LinkTable[srcIndex];
        _LinkTable[srcIndex] = edge;
    }
protected:
    vector<V> _vertexs;//顶点集合
    //边集的数组是指针数组
    vector<Edge*> _LinkTable;//边集
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值