邻接表(C++)
adj_list_network_edge.h
// 邻接表网边数据类模板
template <class WeightType>
class AdjListNetworkEdge
{
public:
// 数据成员:
int adjVex; // 邻接点
WeightType weight; // 权值 // 构造函数模板:
AdjListNetworkEdge(); // 无参数的构造函数模板
AdjListNetworkEdge(int v, WeightType w); // 构造邻接点为v,权为w的邻接边
}; // 邻接表网边数据类模板的实现部分
template <class WeightType>
AdjListNetworkEdge<WeightType>::AdjListNetworkEdge()
// 操作结果:构造一个空邻接表边结点边——无参构造函数模板
{
adjVex = -;
} template <class WeightType>
AdjListNetworkEdge<WeightType>::AdjListNetworkEdge(int v, WeightType w)
// 操作结果:构造邻接点为v,权为w的邻接边
{
adjVex = v; // 邻接点
weight = w; // 权
}
adj_list_graph_vex_node
// 邻接表网顶点结点类模板
template <class ElemType, class WeightType>
class AdjListNetWorkVexNode
{
public:
// 数据成员:
ElemType data; // 数据元素值
LinkList<AdjListNetworkEdge<WeightType> > *adjLink;
// 指向邻接链表的指针 // 构造函数模板:
AdjListNetWorkVexNode(); // 无参数的构造函数模板
AdjListNetWorkVexNode(ElemType item,
LinkList<AdjListNetworkEdge<WeightType> > *adj = NULL);
// 构造顶点数据为item,指向邻接链表的指针为adj的结构
}; // 邻接表网顶点结点类模板的实现部分
template <class ElemType, class WeightType>
AdjListNetWorkVexNode<ElemType, WeightType>::AdjListNetWorkVexNode()
// 操作结果:构造一个空顶点结点——无参构造函数模板
{
adjLink = NULL; // 指向邻接链表的指针为空
} template <class ElemType, class WeightType>
AdjListNetWorkVexNode<ElemType, WeightType>::AdjListNetWorkVexNode(ElemType item,
LinkList<AdjListNetworkEdge<WeightType> > *adj)
// 操作结果:构造数据为item,边为eg的顶点
{
data = item; // 顶点数据
adjLink = adj; // 指向邻接链表的指针
}
adj_list_undir_graph.h
#include "adj_list_graph_vex_node.h" // 邻接表无向图顶点结点类模板 // 无向图的邻接表类模板
template <class ElemType>
class AdjListUndirGraph
{
protected:
// 邻接表的数据成员:
int vexNum, edgeNum; // 顶点个数和边数
AdjListGraphVexNode<ElemType> *vexTable; // 顶点表
mutable StatusCode *tag; // 指向标志数组的指针 // 辅助函数模板:
void DestroyHelp(); // 销毁无向图,释放无向图点用的空间
int IndexHelp(const LinkList<int> *la, int v) const;
//定位顶点v在邻接链表中的位置 public:
// 抽象数据类型方法声明及重载编译系统默认方法声明:
AdjListUndirGraph(ElemType es[], int vertexNum = DEFAULT_SIZE);
// 构造顶点数据为es[],顶点个数为vertexNum,infinit表示无穷大,边数为0的无向图
AdjListUndirGraph(int vertexNum = DEFAULT_SIZE);
// 构造顶点个数为vertexNum,infinit表示无穷大,边数为0的无向图
~AdjListUndirGraph(); // 析构函数模板
StatusCode GetElem(int v, ElemType &e) const;// 求顶点的元素
StatusCode SetElem(int v, const ElemType &e);// 设置顶点的元素值
ElemType GetInfility() const; // 返回无穷大
int GetVexNum() const; // 返回顶点个数
int GetEdgeNum() const; // 返回边数个数
int FirstAdjVex(int v) const; // 返回顶点v的第一个邻接点
int NextAdjVex(int v1, int v2) const; // 返回顶点v1的相对于v2的下一个邻接点
void InsertEdge(int v1, int v2); // 插入顶点为v1和v2的边
void DeleteEdge(int v1, int v2); // 删除顶点为v1和v2的边
StatusCode GetTag(int v) const; // 返回顶点v的标志
void SetTag(int v, StatusCode val) const; // 设置顶点v的标志为val
AdjListUndirGraph(const AdjListUndirGraph<ElemType> ©); // 复制构造函数模板
AdjListUndirGraph<ElemType> &operator =(const AdjListUndirGraph<ElemType> ©); // 重载赋值运算符
}; template <class ElemType>
void Display(const AdjListUndirGraph<ElemType> &g, bool showVexElem); // 显示邻接矩阵无向图 // 无向图的邻接表类模板的实现部分
template <class ElemType>
AdjListUndirGraph<ElemType>::AdjListUndirGraph(ElemType es[], int vertexNum)
// 操作结果:构造顶点数为numVex,顶点数据为es[],顶点个数为vertexNum,边数为0的无向图
{
if (vertexNum < ) throw Error("顶点个数不能为负!");// 抛出异常 vexNum = vertexNum; // 顶点数为vertexNum
edgeNum = ; // 边数为0 tag = new StatusCode[vexNum]; // 生成标志数组
int curPos; // 临时变量
for (curPos = ; curPos < vexNum; curPos++)
{ // 初始化标志数组
tag[curPos] = UNVISITED;
} vexTable = new AdjListGraphVexNode<ElemType>[vexNum];// 生成邻接表
for (curPos = ; curPos < vexNum; curPos++)
{ // 初始化顶点数据
vexTable[curPos].data = es[curPos];
}
} template <class ElemType>
AdjListUndirGraph<ElemType>::AdjListUndirGraph(int vertexNum)
// 操作结果:构造顶点数为numVex,顶点个数为vertexNum,边数为0的无向图
{
if (vertexNum < ) throw Error("顶点个数不能为负!");// 抛出异常 vexNum = vertexNum; // 顶点数为vertexNum
edgeNum = ; // 边数为0 tag = new StatusCode[vexNum]; // 生成标志数组
int curPos; // 临时变量
for (curPos = ; curPos < vexNum; curPos++)
{ // 初始化标志数组
tag[curPos] = UNVISITED;
} vexTable = new AdjListGraphVexNode<ElemType>[vexNum];// 生成邻接表
} template <class ElemType>
void AdjListUndirGraph<ElemType>::DestroyHelp()
// 操作结果:销毁无向图,释放无向图点用的空间
{
delete []tag; // 释放标志
for (int iPos = ; iPos < vexNum; iPos++)
{ // 释放链表
if (vexTable[iPos].adjLink != NULL)
delete vexTable[iPos].adjLink;
}
delete []vexTable; // 释放邻接表
} template <class ElemType>
AdjListUndirGraph<ElemType>::~AdjListUndirGraph()
// 操作结果:释放邻接表无向图所占用空间
{
DestroyHelp();
} template <class ElemType>
StatusCode AdjListUndirGraph<ElemType>::GetElem(int v, ElemType &e) const
// 操作结果:求顶点v的元素, v的取值范围为0 ≤ v < vexNum, v合法时返回
// SUCCESS, 否则返回RANGE_ERROR
{
if (v < || v >= vexNum)
{ // v范围错
return NOT_PRESENT; // 元素不存在
}
else
{ // v合法
e = vexTable[v].data; // 将顶点v的元素值赋给e
return ENTRY_FOUND; // 元素存在
}
} template <class ElemType>
StatusCode AdjListUndirGraph<ElemType>::SetElem(int v, const ElemType &e)
// 操作结果:设置顶点的元素值v的取值范围为0 ≤ v < vexNum, v合法时返回
// SUCCESS, 否则返回RANGE_ERROR
{
if (v < || v >= vexNum)
{ // v范围错
return RANGE_ERROR; // 位置错
}
else
{ // v合法
vexTable[v].data = e; // 顶点元素
return SUCCESS; // 成功
}
} template <class ElemType>
int AdjListUndirGraph<ElemType>::GetVexNum() const
// 操作结果:返回顶点个数
{
return vexNum;
} template <class ElemType>
int AdjListUndirGraph<ElemType>::GetEdgeNum() const
// 操作结果:返回边数个数
{
return edgeNum;
} template <class ElemType>
int AdjListUndirGraph<ElemType>::FirstAdjVex(int v) const
// 操作结果:返回顶点v的第一个邻接点
{
if (v < || v >= vexNum) throw Error("v不合法!");// 抛出异常 if (vexTable[v].adjLink == NULL)
{ // 空邻接链表,无邻接点
return -;
}
else
{ // 非空邻接链表,存在邻接点
int adjVex;
vexTable[v].adjLink->GetElem(, adjVex);
return adjVex;
}
} template <class ElemType>
int AdjListUndirGraph<ElemType>::IndexHelp(const LinkList<int> *la, int v) const
// 操作结果:定位顶点v在邻接链表中的位置
{
int curPos, adjVex;
curPos = la->GetCurPosition(); la->GetElem(curPos, adjVex); // 取得邻接点信息
if (adjVex == v) return curPos; // v为线性链表的当前位置处 curPos = ;
for (curPos = ; curPos <= la->Length(); curPos++)
{ // 循环定定
la->GetElem(curPos, adjVex); // 取得边信息
if (adjVex == v) break; // 定位成功
} return curPos; // curPos = la.Length() + 1 表定失败
} template <class ElemType>
int AdjListUndirGraph<ElemType>::NextAdjVex(int v1, int v2) const
// 操作结果:返回顶点v1的相对于v2的下一个邻接点
{
if (v1 < || v1 >= vexNum) throw Error("v1不合法!"); // 抛出异常
if (v2 < || v2 >= vexNum) throw Error("v2不合法!"); // 抛出异常
if (v1 == v2) throw Error("v1不能等于v2!"); // 抛出异常 if (vexTable[v1].adjLink == NULL) return -; // 邻接链表vexTable[v1].adjList为空,返回-1 int curPos = IndexHelp(vexTable[v1].adjLink, v2); // 取出v2在邻接链表中的位置
if (curPos < vexTable[v1].adjLink->Length())
{ // 存在下1个邻接点
int adjVex;
vexTable[v1].adjLink->GetElem(curPos + , adjVex); // 取出后继
return adjVex;
}
else
{ // 不存在下一个邻接点
return -;
}
} template <class ElemType>
void AdjListUndirGraph<ElemType>::InsertEdge(int v1, int v2)
// 操作结果:插入顶点为v1和v2的边
{
if (v1 < || v1 >= vexNum) throw Error("v1不合法!"); // 抛出异常
if (v2 < || v2 >= vexNum) throw Error("v2不合法!"); // 抛出异常
if (v1 == v2) throw Error("v1不能等于v2!"); // 抛出异常 // 插入<v1, v2>
if (vexTable[v1].adjLink == NULL)
{ // 空链表
vexTable[v1].adjLink = new LinkList<int>;
} int curPos = IndexHelp(vexTable[v1].adjLink, v2); // 取出v2在邻接链表中的位置
if (curPos > vexTable[v1].adjLink->Length())
{ // 不存在边<v1, v2>
vexTable[v1].adjLink->Insert(curPos, v2); // 插入边
edgeNum++; // 边数自增1
} // 插入<v2, v1>
if (vexTable[v2].adjLink == NULL)
{ // 空链表
vexTable[v2].adjLink = new LinkList<int>;
} curPos = IndexHelp(vexTable[v2].adjLink, v1); // 取出v1在邻接链表中的位置
if (curPos > vexTable[v2].adjLink->Length())
{ // 不存在边<v1, v2>
vexTable[v2].adjLink->Insert(curPos, v1); // 插入边
}
} template <class ElemType>
void AdjListUndirGraph<ElemType>::DeleteEdge(int v1, int v2)
// 操作结果:删除顶点为v1和v2的边
{
if (v1 < || v1 >= vexNum) throw Error("v1不合法!"); // 抛出异常
if (v2 < || v2 >= vexNum) throw Error("v2不合法!"); // 抛出异常
if (v1 == v2) throw Error("v1不能等于v2!"); // 抛出异常 int curPos = IndexHelp(vexTable[v1].adjLink, v2); // 取出v2在邻接链表中的位置
if (curPos <= vexTable[v1].adjLink->Length())
{ // 存在边<v1, v2>
vexTable[v1].adjLink->Delete(curPos, v2); // 删除<v1, v2>
edgeNum--; // 边数自减1
} curPos = IndexHelp(vexTable[v2].adjLink, v1); // 取出v1在邻接链表中的位置
if (curPos <= vexTable[v2].adjLink->Length())
{ // 存在边<v2, v1>
vexTable[v2].adjLink->Delete(curPos, v1); // 删除<v2, v1>
}
} template <class ElemType>
StatusCode AdjListUndirGraph<ElemType>::GetTag(int v) const
// 操作结果:返回顶点v的标志
{
if (v < || v >= vexNum) throw Error("v不合法!"); // 抛出异常 return tag[v];
} template <class ElemType>
void AdjListUndirGraph<ElemType>::SetTag(int v, StatusCode val) const
// 操作结果:设置顶点v的标志为val
{
if (v < || v >= vexNum) throw Error("v不合法!"); // 抛出异常 tag[v] = val;
} template <class ElemType>
AdjListUndirGraph<ElemType>::AdjListUndirGraph(const AdjListUndirGraph<ElemType> ©)
// 操作结果:由无向图的邻接矩阵copy构造新无向图的邻接矩阵copy——复制构造函数模板
{
int curPos; // 临时变量
vexNum = copy.vexNum; // 复制顶点数
edgeNum = copy.edgeNum; // 复制边数 tag = new StatusCode[vexNum]; // 生成标志数组
for (curPos = ; curPos < vexNum; curPos++)
{ // 复制标志数组
tag[curPos] = copy.tag[curPos];
} vexTable = new AdjListGraphVexNode<ElemType>[vexNum];// 生成邻接表
for (curPos = ; curPos < vexNum; curPos++)
{ // 复制邻接链表
vexTable[curPos].data = copy.vexTable[curPos].data; // 复制顶点数据
vexTable[curPos].adjLink = new LinkList<int>(*copy.vexTable[curPos].adjLink);
}
} template <class ElemType>
AdjListUndirGraph<ElemType> &AdjListUndirGraph<ElemType>::operator =(const AdjListUndirGraph<ElemType> ©)
// 操作结果:将无向图的邻接矩阵copy赋值给当前无向图的邻接矩阵——重载赋值运算符
{
if (© != this)
{
DestroyHelp(); // 释放当前无向图占用空间 int curPos; // 临时变量
vexNum = copy.vexNum; // 复制顶点数
edgeNum = copy.edgeNum; // 复制边数 tag = new StatusCode[vexNum]; // 生成标志数组
for (curPos = ; curPos < vexNum; curPos++)
{ // 复制标志数组
tag[curPos] = copy.tag[curPos];
} vexTable = new AdjListGraphVexNode<ElemType>[vexNum];// 生成邻接表
for (curPos = ; curPos < vexNum; curPos++)
{ // 复制邻接链表
vexTable[curPos].data = copy.vexTable[curPos].data; // 复制顶点数据
vexTable[curPos].adjLink = new LinkList<int>(*copy.vexTable[curPos].adjLink);
}
}
return *this;
} template <class ElemType>
void Display(const AdjListUndirGraph<ElemType> &g, bool showVexElem = true)
// 操作结果: 显示邻接矩阵无向图
{
for (int v = ; v < g.GetVexNum(); v++)
{ // 显示第v个邻接链表
cout << endl << v << " "; // 显示顶点号
if (showVexElem)
{ // 显示顶点元素
ElemType e; // 数据元素
g.GetElem(v, e); // 取出元素值
cout << e << " "; // 显示顶点元素
} for (int u = g.FirstAdjVex(v); u != -; u = g.NextAdjVex(v, u))
{ // 显示第v个邻接链表的一个结点(表示一个邻接点)
cout << "-->" << u;
}
cout << endl;
}
}
邻接表(C++)的更多相关文章
- 邻接表的广度优先遍历(java版)
到 0 的权是 91 到 2 的权是 31 到 3 的权是 61 到 4 的权是 7 2 到 0 的权是 22 到 3 的权是 5 3 到 0 的权是 33 到 4 的权是 1 4 到 2 的权是 2 ...
- 06-图1 列出连通集 (25分)(C语言邻接表实现)
题目地址:https://pta.patest.cn/pta/test/558/exam/4/question/9495 由于边数E<(n*(n-1))/2 所以我选用了邻接表实现,优先队列用循 ...
- 邻接表有向图(三)之 Java详解
前面分别介绍了邻接表有向图的C和C++实现,本文通过Java实现邻接表有向图. 目录 1. 邻接表有向图的介绍 2. 邻接表有向图的代码说明 3. 邻接表有向图的完整源码 转载请注明出处:http:/ ...
- 邻接表有向图(二)之 C++详解
本章是通过C++实现邻接表有向图. 目录 1. 邻接表有向图的介绍 2. 邻接表有向图的代码说明 3. 邻接表有向图的完整源码 转载请注明出处:http://www.cnblogs.com/skywa ...
- 邻接表有向图(一)之 C语言详解
本章介绍邻接表有向图.在"图的理论基础"中已经对图进行了理论介绍,这里就不再对图的概念进行重复说明了.和以往一样,本文会先给出C语言的实现:后续再分别给出C++和Java版本的实现 ...
- 邻接表无向图(三)之 Java详解
前面分别介绍了邻接表无向图的C和C++实现,本文通过Java实现邻接表无向图. 目录 1. 邻接表无向图的介绍 2. 邻接表无向图的代码说明 3. 邻接表无向图的完整源码 转载请注明出处:http:/ ...
- 邻接表无向图(二)之 C++详解
本章是通过C++实现邻接表无向图. 目录 1. 邻接表无向图的介绍 2. 邻接表无向图的代码说明 3. 邻接表无向图的完整源码 转载请注明出处:http://www.cnblogs.com/skywa ...
- 邻接表无向图(一)之 C语言详解
本章介绍邻接表无向图.在"图的理论基础"中已经对图进行了理论介绍,这里就不再对图的概念进行重复说明了.和以往一样,本文会先给出C语言的实现:后续再分别给出C++和Java版本的实现 ...
- poj3013 邻接表+优先队列+Dij
把我坑到死的题 开始开题以为是全图连通是的最小值 ,以为是最小生成树,然后敲了发现不是,看了下别人的题意,然后懂了: 然后发现数据大,要用邻接表就去学了一下邻接表,然后又去学了下优先队列优化的dij: ...
- HDU 1874 畅通工程续(最短路/spfa Dijkstra 邻接矩阵+邻接表)
题目链接: 传送门 畅通工程续 Time Limit: 1000MS Memory Limit: 65536K Description 某省自从实行了很多年的畅通工程计划后,终于修建了很多路. ...
随机推荐
- 转换编码,将Unicode编码转换成可以浏览的utf-8编码
//转换编码,将Unicode编码转换成可以浏览的utf-8编码 public function unicodeDecode($name) { $pattern = '/([\w]+)|(\\\u([ ...
- 从Java虚拟机的内存区域、垃圾收集器及内存分配原则谈Java的内存回收机制
一.引言: 在Java中我们只需要轻轻地new一下,就可以为实例化一个类,并分配对应的内存空间,而后似乎我们也可以不用去管它,Java自带垃圾回收器,到了对象死亡的时候垃圾回收器就会将死亡对象的内存回 ...
- Selenium chrome配置不加载图片Python版
环境: windows 7 + Python 3.5.2 + Selenium 3.4.2 + Chrome Driver 2.29 + Chrome 58.0.3029.110 (64-bit) f ...
- php打包文件为ZIP包后下载到本地
这是一个工作中需要打包下载当前产品的所有图片到本地,文件格式为ZIP压缩包,打包下载文件跟图片一样,本程序细节为实际情况,使用需按照自己实际情况书写:<?php/**************** ...
- 14.如何解决使用webpack打包之后,font-awsome路径不对的问题,终极解决方法
问题描述: 使用webpack打包vue项目,使用font-awsome字体,发现打包之后,font-awsome图标不显示,报错为路径不对 看了下打包的路径,的确路径不对,打包之后font-awso ...
- 4.Smarty模板之间调用
{include file="header.tpl" name="cai"}
- 浙江省新高中信息技术教材,将围绕Python进行并增加编程相关知识点
2017年初消息: 浙江省信息技术新教材,即将在2017级(2017年9月入学)高中新生中开始使用. 据了解,与目前的选考(可以理解为高考科目)要求的信息技术教材由3本<信息技术基础>.& ...
- Angular基础(一)
AngularJS有五个主要核心特性,如下介绍: 双向数据绑定 -- 实现了把model与view完全绑定在一起,model变化,view也变化,反之亦然. 模板 -- 在AngularJS中,模板相 ...
- Java编程练习(四)——集合框架应用
Java集合框架小应用之扑克牌小游戏 学习了Java集合框架之后,我写了一个扑克牌小游戏来巩固知识.学习之余的练习之作,有不足之处还得多多指教了~(*/ω\*) 扑克牌小游戏背景: 1. 创建一副扑克 ...
- 谷歌是如何做代码审查的 | 外刊IT评论 - Google Chrome
谷歌是如何做代码审查的 本文的作者 Mark CC 在上一篇文章中提到过,我已经不在Google工作了.我还没有想清楚应该去哪里-有两三个非常好的工作机会摆在我面前.因为在这段做决 ...