图的储存结构(邻接表)
图用邻接矩阵储存时,是用的一个二维数组,操作这个图的时候就相当于操作这个二维数组。但一但使用数组时就有一个很明显的缺点,那就是动态扩容性,基于邻接矩阵的图不能添加节点,只能添加边。如果图是一个节点非常多的稀疏图,比如说这个n为一亿,那么所需要的内存就是100000000 * 100000000 = 10000000000000000个单位,而其中非常多的内存是被浪费了的。因而可以使用另外一种储存结构——邻接表来储存图。邻接表是在一维的基础上进行扩展的,把节点排列成一维的线性表,然后线性表的每个元素又是一个链表,这条链的头就是当前节点,而链中的元素就是这个节点在图中的邻接节点,把邻接节点按序号排列成一个线性链。这样的好处就是只储存了有意义的关系,不会像邻接矩阵那样浪费没有连接关系的储存单元。
下面是用邻接表来实现图
#pragma once
#ifndef ADJLISTDIRGRAPH
#define ADJLISTDIRGRAPH
#include "graph.h"
#include "linklist.h"
namespace dataStructure
{
template<typename T>
struct AdjListGraphNode
{
T data;
int tag;
LinkList<int> *adjLink = NULL;
};
template<typename T>
class AdjListDirGraph:public Graph<T>
{
public:
AdjListDirGraph();
~AdjListDirGraph();
bool InsertNode(const T &t);
bool DeleteNode(const int v);
//获取节点的值
bool GetElem(int v, T &t);
//设置节点的值
bool SetElem(int v, const T &t);
//返回节点元素
T GetVexData(int v)const;
//返回节点个数
int GetVexNum()const;
//返回边数
int GetEdgeNum()const;
//返回第一个邻接点
int FirstAdjVex(int v)const;
//返回下一个邻接点
int NextAdjVex(int v1, int v2)const;
//插入一条边
void InsertEdge(int v1, int v2);
//删除一条边
void DeleteEdge(int v1, int v2);
//获取节点上的标志
bool GetTag(int v, int &tag)const;
//设置节点上的标志
bool SetTag(int v, const int &tag);
//深搜
void DFSTraverse(void(*visit)(const T &t))const;
//广搜
void BFSTraverse(void(*visit)(const T &t))const;
private:
int vexNum, edgeNum;
LinkList<AdjListGraphNode<T>*>