题目描述:

已知有n个顶点的有向图G的邻接表,设计算法求邻接表G的逆邻接表。

思路:

将邻接表转化为逆邻接表需要遍历所有邻接表的整个顶点表G,然后便可得到每个顶点有哪些顶点指向它,然后将其信息放入逆邻接表GIn中(由邻接表可以得到所有顶点的出度,逆邻接表则得到的是入度)

我们首先以下图这个有向图为例子,得到一个输入样例:

6 8
1 2
1 4
4 2
2 5
5 4
3 5
3 6
6 6

样例输出如下:

图的邻接表存储结构定义如下

const int MaxVertexNum = 100; // 图中顶点数目的最大值
typedef struct ArcNode { //边表结点int adjvex; // 该弧所指向的顶点的位置struct ArcNode *next; //指向下一条弧的指针// int weight; //网的边权值// Infotype info;
}ArcNode;
typedef struct VNode { //顶点表结点int data; //顶点信息 (VertexType data;)ArcNode *first; // 指向第一条依附该顶点的弧的指针
}VNode, AdjList[MaxVertexNum];
typedef struct {AdjList vertices; //邻接表int vexnum, arcnum; //图的顶点数和弧数
}ALGraph; // ALGraph是以邻接表存储的图类型

创建邻接表的算法如下

void Create_AdjList_Graph(ALGraph &G) { //创建一个邻接表scanf("%d%d", &G.vexnum, &G.arcnum); //输入图的顶点数和边数for(int i = 1; i <= G.vexnum; i++) {G.vertices[i].data = i; //假设顶点信息是1....vernumG.vertices[i].first = NULL; //初始化第一条依附该顶点的弧的指针为空}ArcNode *p;for(int i = 0; i < G.arcnum; i++) {int u, v;scanf("%d%d", &u, &v); //u, v表示u有一条边指向v;p = (ArcNode *) malloc (sizeof(ArcNode)); // p = new ArcNode;p -> adjvex = v;p -> next = G.vertices[u].first; //用头插法将v插到结点u的边表结点中G.vertices[u].first = p; // 插入后将第一条依附该顶点的弧的指针修改为p}
}

邻接表转逆邻接表算法如下

void adjacency_to_inverse_adjacency(ALGraph GOut, ALGraph &GIn) { /*将图的邻接表转化为逆邻接表*/GIn.arcnum = GOut.arcnum; //初始化逆邻接表的边数目GIn.vexnum = GOut.vexnum; //初始化逆邻接表的顶点数目for (int i = 1; i <= GIn.vexnum; i++) { GIn.vertices[i].data = GOut.vertices[i].data; // 初始化逆邻接表的顶点信息GIn.vertices[i].first = NULL; // 初始化指向第一条依附该顶点的弧的指针}for(int i = 1; i <= GOut.vexnum; i++) {ArcNode *p = GOut.vertices[i].first; // 取得指向第一条依附该顶点的弧的指针ArcNode *s;while(p != NULL) { // 遍历邻接表中第i个顶点所有邻接边 s = (ArcNode *) malloc (sizeof(ArcNode)); // or s = new ArcNode;int temp = p -> adjvex;s -> adjvex = i;s -> next = GIn.vertices[temp].first; //头插法将顶点i挂到GIn.vertices[temp]的边表中GIn.vertices[temp].first = s;p = p -> next; // 继续往后遍历i所指向的顶点}}
}

完整可执行代码如下

#include<bits/stdc++.h>
using namespace std;
const int MaxVertexNum = 100; // 图中顶点数目的最大值
typedef struct ArcNode { //边表结点int adjvex; // 该弧所指向的顶点的位置struct ArcNode *next; //指向下一条弧的指针// int weight; //网的边权值// Infotype info;
}ArcNode;
typedef struct VNode { //顶点表结点int data; //顶点信息 (VertexType data;)ArcNode *first; // 指向第一条依附该顶点的弧的指针
}VNode, AdjList[MaxVertexNum];
typedef struct {AdjList vertices; //邻接表int vexnum, arcnum; //图的顶点数和弧数
}ALGraph; // ALGraph是以邻接表存储的图类型
void Create_AdjList_Graph(ALGraph &G) { //创建一个邻接表scanf("%d%d", &G.vexnum, &G.arcnum); //输入图的顶点数和边数for(int i = 1; i <= G.vexnum; i++) {G.vertices[i].data = i; //假设顶点信息是1....vernumG.vertices[i].first = NULL; //初始化第一条依附该顶点的弧的指针为空}ArcNode *p;for(int i = 0; i < G.arcnum; i++) {int u, v;scanf("%d%d", &u, &v); //u, v表示u有一条边指向v;p = (ArcNode *) malloc (sizeof(ArcNode)); // p = new ArcNode;p -> adjvex = v;p -> next = G.vertices[u].first; //用头插法将v插到结点u的边表结点中G.vertices[u].first = p; // 插入后将第一条依附该顶点的弧的指针修改为p}
}
void adjacency_to_inverse_adjacency(ALGraph GOut, ALGraph &GIn) { /*将图的邻接表转化为逆邻接表*/GIn.arcnum = GOut.arcnum; //初始化逆邻接表的边数目GIn.vexnum = GOut.vexnum; //初始化逆邻接表的顶点数目for (int i = 1; i <= GIn.vexnum; i++) { GIn.vertices[i].data = GOut.vertices[i].data; // 初始化逆邻接表的顶点信息GIn.vertices[i].first = NULL; // 初始化指向第一条依附该顶点的弧的指针}for(int i = 1; i <= GOut.vexnum; i++) {ArcNode *p = GOut.vertices[i].first; // 取得指向第一条依附该顶点的弧的指针ArcNode *s;while(p != NULL) { // 遍历邻接表中第i个顶点所有邻接边 s = (ArcNode *) malloc (sizeof(ArcNode)); // or s = new ArcNode;int temp = p -> adjvex;s -> adjvex = i;s -> next = GIn.vertices[temp].first; //头插法将顶点i挂到GIn.vertices[temp]的边表中GIn.vertices[temp].first = s;p = p -> next; // 继续往后遍历i所指向的顶点}}
}
void print(ALGraph G) { // 打印邻接表for(int i = 1; i <= G.vexnum; i++) {printf("(%d) ", i);ArcNode *p = G.vertices[i].first;while(p) {printf("-> %d ", p -> adjvex);p = p -> next;}puts("");}
}
int main() {ALGraph GraphOut, GraphIn; // GraphOut为邻接表,GraphIn为逆邻接表Create_AdjList_Graph(GraphOut); // 构造邻接表cout << endl;print(GraphOut); //打印邻接表adjacency_to_inverse_adjacency(GraphOut, GraphIn);cout << endl;print(GraphIn); //打印逆邻接表return 0;
}
/*
测试样例二:
9 14
1 2
1 3
2 5
2 4
5 3
5 4
5 6
6 5
3 8
8 9
9 6
4 7
7 6
7 9
*/

小结:
由于没有在各大oj上找到这么一道题可以测试自己代码的正确性,所以自己也就简单地测试了几组数据,如有不足的地方,欢迎大家指出来以及请大家见谅,指出来之后我会尽快修改。

邻接表转化为逆邻接表相关推荐

  1. python一维表二维表转化

    效果: import pandas as pd# 读入数据: df = pd.read_excel(r'C:\Users\lihwa11\Desktop\Python\code\data\one.xl ...

  2. 图的链式存储结构解析(邻接表、逆邻接表、十字链表、邻接多重表)

    图的矩阵表示法比较消耗空间,需要花费$ n 2 n^2 n2$个单元存储边(弧).在边数较少的情况下比较浪费.我们这里来讨论图的链式存储结构. 图的链式结构主要有四类:邻接表.逆邻接表.十字链表.邻接 ...

  3. mysql 邻接表_图的邻接表存储结构详解

    通常,图更多的是采用链表存储,具体的存储方法有 3 种,分别是邻接表.邻接多重表和十字链表. 本节先讲解图的邻接表存储法.邻接表既适用于存储无向图,也适用于存储有向图. 在具体讲解邻接表存储图的实现方 ...

  4. 邻接表1试在邻接表存储结构上实现图的基本操作 insert_vertex 和 insert_arc,相关定义如下:icoding---算法改进--配详细注释

    邻接表1 试在邻接表存储结构上实现图的基本操作 insert_vertex 和 insert_arc,相关定义如下: typedef int VertexType; typedef enum{DG, ...

  5. 邻接表2 -试在邻接表存储结构上实现图的基本操作 del_vertex-数据结构-图-icoding

    邻接表2 试在邻接表存储结构上实现图的基本操作 del_vertex,相关定义如下: typedef int VertexType;typedef enum{DG, UDG }GraphType;ty ...

  6. 邻接表1 - 试在邻接表存储结构上实现图的基本操作 insert_vertex 和 insert_arc-数据结构-图-icoding

    邻接表1 试在邻接表存储结构上实现图的基本操作 insert_vertex 和 insert_arc,相关定义如下: typedef int VertexType;typedef enum{DG, U ...

  7. R语言将dataframe长表转化为宽表实战:使用reshape函数、使用tidyr包的spread函数、使用data.table

    R语言将dataframe长表转化为宽表实战:使用reshape函数.使用tidyr包的spread函数.使用data.table 目录

  8. R语言将dataframe宽表转化为长表实战:使用data.table、使用tidyr包gather函数、使用reshape2包

    R语言将dataframe宽表转化为长表实战:使用data.table.使用tidyr包gather函数.使用reshape2包 目录

  9. 数据结构:顺序表的就地逆置

    顺序表的就地逆置 前言 用于个人作业记录 题目 Chapter 2, HLOJ 9503,例2.6.1 顺序表的就地逆置 试写一算法,实现顺序表的就地逆置,即利用原表的存储空间将线性表(a1,a2,- ...

最新文章

  1. centos7 yum安装 c c++ gcc gcc-c++
  2. linux pyside2 安装包,Qt for Python 5.12发布下载,附PySide2和Shiboken2介绍
  3. 通往自由之路 | 云队友远程办公征文活动
  4. Matlab R2018a版离线使用帮助文档方法
  5. mysql压缩包修改密码_mysql 解压之后一堆文件,第一次安装 与 修改密码
  6. HDU - 2222 Keywords Search(AC自动机)
  7. ideal pom文件安装到maven库中_java学习之web基础(14)Maven基础学习
  8. myelicpes怎么导入PHP项目,利用PHP执行SQL文件,将SQL文件导入到数据库
  9. LeetCode 278. First Bad Version
  10. 【昇腾】【玩转Atlas200DK系列】为Atlas 200 DK制作python环境离线安装包
  11. jsp 与html 如何结合使用方法,jsp中如何写javascript?
  12. 【天梯选拔月赛】寻宝路线(dp)
  13. 学生管理系统总结(c语言)
  14. python批量检测域名和url能否打开
  15. rtklib-RINEX文件读取-rinex.c解析(一)
  16. 辩证唯物主义和历史唯物主义思维导图 - 圣才
  17. 《TCP/IP详解 卷1:协议》学习笔记(未完待续)
  18. 已解决:git push代码出现Support for password authentication was removed on August 13, 2021.
  19. 史上最全最实用的生活小窍门
  20. 玩转SQLite5:使用Python来读写数据库

热门文章

  1. 【译】.NET 7 中的性能改进(一)
  2. SQL--数据库的操作(DDL,DML,DQL)+使用命令查看当前数据库的存储位置(数据库版本查询)
  3. 目标检测综述:Object Detection in 20 Years: A Survey
  4. 某肠派对过模拟器检测(已过期)
  5. python合并多个txt
  6. 祁文之恋——我的包子
  7. three.js 颜色color的几种设置方式
  8. QNAP NAS固件更新失败的手工处理
  9. 使用Python开发spark
  10. (2)shell编程学习 Shell中的变量(预设变量表)及变量定义与特殊变量 (脚本小子的进阶之路)