入度与出度在数据结构中的应用


入度和出度是图论中的概念,主要应用于有向图的数据结构中。这些概念并不直接划分数据结构的类型,而是描述有向图中顶点的特性。然而,理解入度和出度有助于我们分析和操作不同类型的图数据结构。以下是几种与有向图及其入度、出度概念紧密相关的数据结构:

  1. 邻接矩阵:

    • 邻接矩阵是一种使用二维数组来表示图中顶点之间连接关系的数据结构。对于有向图,矩阵的第i行第j列的值表示从顶点i到顶点j的边的存在与否,以及可能的权重。通过遍历矩阵的行可以轻易计算出每个顶点的出度,遍历列则可得到入度。其空间复杂度为O(|V|^2),其中|V|是顶点的数量。
  2. 邻接链表:

    • 邻接链表是另一种常用的图表示方法,特别适合边较少的稀疏图。每个顶点都有一个链表,链表中包含了所有从该顶点出发的边(即出度信息),链表中的节点通常会包含指向目标顶点的指针或索引以及边的权重等信息。为了获取入度,通常需要额外的数据结构,如逆邻接链表,或者遍历所有链表来统计指向每个顶点的边数。
  3. 入度列表(或称为逆邻接链表):

    • 当需要频繁查询顶点的入度时,可以维护一个额外的链表或数组来直接记录每个顶点的入度情况。每个顶点对应的链表或数组条目存储了所有指向该顶点的边的信息,这使得计算入度变得直接且高效。
  4. 邻接多重表:

    • 对于允许每对顶点间有多条边(多重图)的情况,邻接多重表会在邻接链表的基础上为每个顶点对维护一个链表,链表中包含了所有从一个顶点到另一个顶点的边。这种结构同时方便了出度和入度的计算,尽管它比基本的邻接链表或矩阵更为复杂,占用更多的内存。

这些数据结构都是围绕图的表示和操作设计的,入度和出度的概念在这些结构中用于描述图中顶点的连接特性,并非直接划分数据结构类型,而是作为这些结构中顶点属性的一部分被考量。

应用案例

针对入度与出度的计算,我们将分别展示四种数据结构的具体应用案例:邻接矩阵、邻接链表、邻接集(使用Python字典实现),以及通过邻接链表计算后生成的入度列表。这里,我们以一个简单的有向图为例,包含顶点集合['A', 'B', 'C', 'D'],以及边集合['A'->'B', 'A'->'C', 'B'->'C', 'C'->'D', 'D'->'A']

1. 邻接矩阵

def adjacency_matrix(degrees):
    n = len(degrees)
    matrix = [[0]*n for _ in range(n)]
    for from_v, to_vs in degrees.items():
        for to_v in to_vs:
            matrix[ord(from_v) - ord('A')][ord(to_v) - ord('A')] = 1
    return matrix

degrees = {'A': ['B', 'C'], 'B': ['C'], 'C': ['D'], 'D': ['A']}
matrix = adjacency_matrix(degrees)
# 计算入度和出度
out_degrees = [sum(row) for row in matrix]
in_degrees = [sum(col) for col in zip(*matrix)]
print("邻接矩阵表示:")
print(*matrix, sep='\n')
print("出度:", out_degrees)
print("入度:", in_degrees)

2. 邻接链表

class Graph:
    def __init__(self):
        self.adj_list = {}

    def add_edge(self, from_v, to_v):
        if from_v not in self.adj_list:
            self.adj_list[from_v] = []
        self.adj_list[from_v].append(to_v)

    def calculate_degrees(self):
        in_degrees = {v: 0 for v in self.adj_list}
        out_degrees = {v: 0 for v in self.adj_list}

        for from_v, to_vs in self.adj_list.items():
            out_degrees[from_v] = len(to_vs)
            for to_v in to_vs:
                in_degrees[to_v] += 1

        return in_degrees, out_degrees

graph = Graph()
graph.add_edge('A', 'B')
graph.add_edge('A', 'C')
graph.add_edge('B', 'C')
graph.add_edge('C', 'D')
graph.add_edge('D', 'A')

in_degrees, out_degrees = graph.calculate_degrees()
print("邻接链表表示:")
print("出度:", out_degrees)
print("入度:", in_degrees)

3. 邻接集(字典实现)

def adjacency_set(degrees):
    graph_dict = {v: set() for v in degrees}
    for from_v, to_vs in degrees.items():
        for to_v in to_vs:
            graph_dict[from_v].add(to_v)
    return graph_dict

# 注意:直接使用邻接集计算入度不如邻接链表直观,因此计算入度时通常需要额外处理或转换
graph_dict = adjacency_set(degrees)
out_degrees = {v: len(edges) for v, edges in graph_dict.items()}
# 计算入度需要额外逻辑,此处略去直接展示结果
print("邻接集表示:")
print("出度:", out_degrees)
# 实际应用中,可能需要遍历所有边,统计每个顶点作为目标的次数来获得入度

4. 入度列表(基于邻接链表计算)

由于直接计算入度列表通常依赖于邻接链表或其他形式的图表示,上述邻接链表示例中已隐含了如何生成入度列表。这里不单独列出新代码,因为计算入度列表的过程已经在邻接链表的示例中体现出来,即通过遍历邻接链表并计数。

以上代码展示了不同数据结构下如何表示有向图以及如何计算每个顶点的入度和出度。请注意,实际应用中根据具体需求选择合适的数据结构,以达到最优的性能和资源利用率。

特别补充

为了进一步完善解释并提供一个全面的理解,让我们通过一个额外的例子来展示如何直接从邻接集计算入度,同时简要介绍一种高级数据结构——邻接多重表,它在处理具有多重边的图时特别有用。

3. 邻接集计算入度(补充)

前面提到,从邻接集直接计算入度不如邻接链表直观,但可以通过遍历整个邻接集来实现。下面是完成这一过程的代码补充:

def calculate_in_degrees(adjacency_set):
    in_degrees = {vertex: 0 for vertex in adjacency_set}
    for edges in adjacency_set.values():
        for edge in edges:
            in_degrees[edge] += 1
    return in_degrees

# 使用之前的邻接集示例
graph_dict = adjacency_set(degrees)
in_degrees = calculate_in_degrees(graph_dict)
print("基于邻接集计算的入度:", in_degrees)

4. 邻接多重表(概念介绍)

邻接多重表是针对含有重边(两个顶点之间有多条边)和自环的图的一种数据结构。它扩展了邻接链表的概念,每个链表项不仅包含指向下一个节点的指针,还记录了该边的权值(如果图是有权图的话)以及边的数量。对于无权图,只需记录边的数量。

虽然不提供具体代码实现,邻接多重表的基本结构可以描述如下:

顶点A -> (边数: 2, 指向B的链表) -> 顶点B -> (边数: 1, 指向C的链表) -> 顶点C ...

在这个结构中,每个链表头会有一个计数器说明该链表包含了多少条指向后续顶点的边。如果有向图中允许存在多条从一个顶点到另一个顶点的边,邻接多重表能准确地反映这一点,并且便于快速计算出度和入度。

总结而言,不同的数据结构适用于图的不同特性和操作需求。邻接矩阵适合于稠密图和需要快速查询两点间是否存在边的场景;邻接链表和邻接集(字典)则更适合稀疏图,特别是当关注空间效率或频繁进行遍历时;而邻接多重表则专为处理具有多重边的图设计。

😍😍 海量H5小游戏、微信小游戏、Web casualgame源码😍😍
😍😍试玩地址: https://www.bojiogame.sg😍😍
😍看上哪一款,需要源码的csdn私信我😍

————————————————

​最后我们放松一下眼睛
在这里插入图片描述

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极致人生-010

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值