c语言邻接表,C++数据结构之实现邻接表

本文介绍了C++中基于邻接表实现图的详细代码,包括有向图、无向图、有向网、无向网的创建、边的增删、深度优先和广度优先遍历。文章分析了邻接表存储结构的优缺点,并提供了测试代码展示不同类型的图遍历序列。
摘要由CSDN通过智能技术生成

本文实例为大家分享了C++数据结构之实现邻接表的具体代码,供大家参考,具体内容如下

一、图的邻接表实现

1.实现了以顶点顺序表、边链表为存储结构的邻接表;

2.实现了图的创建(有向/无向/图/网)、边的增删操作、深度优先递归/非递归遍历、广度优先遍历的算法;

3.采用顶点对象列表、边(弧)对象列表的方式,对图的创建进行初始化;引用 "ObjArrayList.h"头文件,头文件可参看之前博文“数据结构之顺序列表(支持对象元素)”代码;

4.深度优先遍历分别采用递归/非递归算法;非递归中用到的栈,引用"LinkStack.h"头文件,头文件可参看之前博文“数据结构之栈”代码;

5.广度优先遍历采用队列方式实现;用到的队列,引用 "LinkQueue.h"头文件,头文件可参看之前博文“数据结构之队列”代码;

6.测试代码中以有向网的所有带权边作为边的初始化数据,选择图类型(DG, UDG, DN, UDN)可创建成不同类型的图。

7.优劣分析:

7.1.(优势)邻接表存储结构,相比邻接矩阵,消除了无邻接关系顶点的边存储空间;

7.2.(优势)邻接表比邻接矩阵更容易访问某顶点的邻接顶点;

7.3.(优势)邻接表比邻接矩阵更易于统计边总数,无需逐行逐列遍历;

7.4.(劣势)在确定两顶点间是否有边的搜索过程中,邻接表不如邻接矩阵可直接寻址快,反而需要顶点到边链的遍历;

7.5.(劣势)邻接矩阵在删除顶点时,只需清除对应行列数据即可;而邻接表在清除顶点指向的边链后,还需遍历整个边表,清除所有邻接于此顶点的边结点;

7.6.(不足)邻接表在统计有向图出度时容易,只需遍历依附此顶点的边链;却在统计其入度时,需要遍历整个边表,比较麻烦;可采用十字链表(邻接表与逆邻接表的结合)解决这个问题;

7.7.(不足)邻接表在无向图的存储中,属于行列对称矩阵形式,因此会有一半重复的边数据,故可采用邻接多重表,只存储一半边,来优化存储。

二、测试代码中的图结构

72f39d0886b1b96de7e9f0b46e2e8e5f.png

深度优先遍历序列(从 v1 顶点开始):

1.无向图/网:v1-v2-v3-v5-v4-v6-v7

2.有向图/网:v1-v2-v5-v3-v4-v6-v7

广度优先遍历序列(从 v2 顶点开始):

1.无向图/网:v2-v1-v3-v5-v4-v6-v7

2.有向图/网:v2-v5 后序无法遍历

注:有向图的遍历 是遵循出度方向遍历的,若无出度方向,则遍历终止。

4a791d89e14f9c42a3e04bc626cece23.png

c6ca9be512db3c9b33f108937839119e.png

三、代码

//文件名:"GraphAdjList.h"

#pragma once

#ifndef GRAPHADJLISL_H_

#define GRAPHADJLISL_H_

#include

#include "ObjArrayList.h"

using namespace std;

/*

. 图(邻接表实现) Graph Adjacency List

. 相关术语:

. 顶点 Vertex ; 边 Arc ;权 Weight ;

. 有向图 Digraph ;无向图 Undigraph ;

. 有向网 Directed Network ;无向网 Undirected Network ;

. 存储结构:

. 1.顶点表只能采用顺序结构。(因为若采用链式结构,顶点结点定义与边表结点定义就相互引用,无法定义)

. 2.边表采用链表结构。

*/

class GraphAdjList

{

/*

. 边表(链表)结点

*/

struct ArcNode

{

int adjVex; //邻接顶点所在表中下标

int weight; //边权重

ArcNode * next; //下一条边

};

/*

. 顶点表(顺序表)结点

*/

struct VNode

{

string name; //顶点名

ArcNode * first; //指向的第一个依附该顶点的顶点边结点

};

public:

/*

. 图 种类

*/

enum GraphType

{

DG, //有向图,默认 0

UDG, //无向图,默认 1

DN, //有向网,默认 2

UDN //无向网,默认 3

};

/*

. 边(弧)数据,注:供外部初始化边数据使用

*/

struct ArcData

{

string Tail; //弧尾

string Head; //弧头

int Weight; //权重

};

private:

static const int _MAX_VERTEX_NUM = 10; //支持最大顶点数

VNode vexs[_MAX_VERTEX_NUM]; //顶点表

int vexs_visited[_MAX_VERTEX_NUM]; //顶点访问标记数组:0|未访问 1|已访问

int vexNum; //顶点数

int arcNum; //边数

int type; //图种类

void _CreateVexSet(ObjArrayList * vexs); //创建顶点集合

void _CreateDG(ObjArrayList * arcsList); //创建有向图

void _CreateUDG(ObjArrayList * arcsList); //创建无向图

void _CreateDN(ObjArrayList * arcsList); //创建有向网

void _CreateUDN(ObjArrayList * arcsList); //创建无向网

int _Locate(string vertex); //定位顶点元素位置

void _InsertArc(int tail, int head, int weight); //插入边(元操作,不分有向/无向)

void _DeleteArc(int tail, int head); //删除边(元操作,不分有向/无向)

void _DFS_R(int index); //深度优先遍历 递归

void _DFS(int index); //深度优先遍历 非递归

public:

GraphAdjList(int type); //构造函数:初始化图种类

~GraphAdjList(); //析构函数

void Init(ObjArrayList * vexs, ObjArrayList * arcsList); //初始化顶点、边数据为 图|网

void InsertArc(ArcData * arcData); //插入边(含有向/无向操作)

void DeleteArc(ArcData * arcData); //删除边(含有向/无向操作)

void Display(); //显示 图|网

void Display_DFS_R(string *vertex); //从指定顶点开始,深度优先 递归 遍历

void Display_D

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值