首页 > 编程语言 >python中的图

python中的图

时间:2025-01-06 20:55:25浏览次数:1  
标签:node python graph queue neighbor visited 节点

在 Python 中,图(Graph)是一个非常重要的数据结构,特别是在刷算法题时。图有许多类型(如有向图、无向图、有权图、无权图等),并且涉及的算法(如深度优先搜索、广度优先搜索、最短路径等)都非常常见。以下是 Python 中常见的图的语法,尤其是刷算法题时用到的技巧。

1. 图的基本定义

图通常由两部分组成:

  • 顶点(节点):图中的每个元素。
  • 边(连接顶点的线):连接两个顶点的关系。

Python 中表示图的方式有两种常见的方式:

  • 邻接矩阵:使用一个二维数组来表示图。
  • 邻接表:使用字典或列表来存储每个节点的相邻节点(边)。

1.1 邻接矩阵

邻接矩阵适用于存储密集图(边较多的图)。每个节点与其他节点之间的边存在于一个二维矩阵中,matrix[i][j] 为 1 表示有边从节点 i 到节点 j,为 0 则表示没有。

# 使用二维列表表示图
n = 5  # 图的顶点数量
graph = [[0] * n for _ in range(n)]

# 假设图是无向图,添加边 (0, 1) 和 (1, 2)
graph[0][1] = 1
graph[1][0] = 1
graph[1][2] = 1
graph[2][1] = 1

# 打印邻接矩阵
for row in graph:
    print(row)

1.2 邻接表

邻接表更适合稀疏图(边较少的图)。它使用一个字典或列表,键表示图的节点,值为该节点的所有相邻节点。

# 使用字典表示图
graph = {
    0: [1, 2],  # 0 节点与 1 和 2 相连
    1: [0, 2],  # 1 节点与 0 和 2 相连
    2: [0, 1],  # 2 节点与 0 和 1 相连
    3: [4],     # 3 节点与 4 相连
    4: [3]      # 4 节点与 3 相连
}

# 打印邻接表
for node, neighbors in graph.items():
    print(f"Node {node}: {neighbors}")

2. 图的遍历:深度优先搜索 (DFS) 和广度优先搜索 (BFS)

在图算法中,遍历是常见的操作。常用的图遍历算法有 深度优先搜索(DFS)和 广度优先搜索(BFS)。

2.1 深度优先搜索 (DFS)

深度优先搜索是从一个节点开始,尽可能深入地访问每一个节点,直到没有未访问的邻居节点。DFS 可以使用递归或栈来实现。

递归实现 DFS

# 使用邻接表表示图
graph = {
    0: [1, 2],
    1: [0, 2],
    2: [0, 1],
    3: [4],
    4: [3]
}

# 递归实现 DFS
def dfs(graph, node, visited):
    print(node, end=" ")
    visited.add(node)
    for neighbor in graph[node]:
        if neighbor not in visited:
            dfs(graph, neighbor, visited)

visited = set()
dfs(graph, 0, visited)  # 从节点 0 开始 DFS

非递归实现 DFS(使用栈):

# 使用栈实现 DFS
def dfs_iterative(graph, start):
    visited = set()
    stack = [start]
    while stack:
        node = stack.pop()
        if node not in visited:
            visited.add(node)
            print(node, end=" ")
            for neighbor in graph[node]:
                if neighbor not in visited:
                    stack.append(neighbor)

dfs_iterative(graph, 0)  # 从节点 0 开始 DFS

2.2 广度优先搜索 (BFS)

广度优先搜索是从起始节点开始,依次访问离起始节点较近的节点,逐层扩展。BFS 通常使用队列来实现。

from collections import deque

# 使用队列实现 BFS
def bfs(graph, start):
    visited = set()
    queue = deque([start])
    while queue:
        node = queue.popleft()
        if node not in visited:
            visited.add(node)
            print(node, end=" ")
            for neighbor in graph[node]:
                if neighbor not in visited:
                    queue.append(neighbor)

bfs(graph, 0)  # 从节点 0 开始 BFS

3. 常见图算法

3.1 最短路径算法

Dijkstra 算法(适用于有权图):
Dijkstra 算法用于寻找从起点到所有其他节点的最短路径,适用于图中的边权为正的情况。

import heapq

def dijkstra(graph, start):
    # 初始化最短路径
    dist = {node: float('inf') for node in graph}
    dist[start] = 0
    priority_queue = [(0, start)]  # (distance, node)

    while priority_queue:
        d, node = heapq.heappop(priority_queue)

        if d > dist[node]:
            continue

        for neighbor, weight in graph[node]:
            distance = d + weight
            if distance < dist[neighbor]:
                dist[neighbor] = distance
                heapq.heappush(priority_queue, (distance, neighbor))

    return dist

# 使用邻接表表示图,图中的每个边是 (邻居, 权重)
graph = {
    0: [(1, 4), (2, 1)],
    1: [(2, 2), (3, 5)],
    2: [(3, 1)],
    3: []
}

print(dijkstra(graph, 0))  # 从节点 0 开始计算最短路径

3.2 拓扑排序

拓扑排序用于有向无环图(DAG)。它可以找到一个节点的线性排列,使得每个节点的前驱节点都在其之前。

from collections import deque

def topological_sort(graph):
    # 计算每个节点的入度
    in_degree = {node: 0 for node in graph}
    for node in graph:
        for neighbor in graph[node]:
            in_degree[neighbor] += 1
    
    # 将入度为 0 的节点加入队列
    queue = deque([node for node in in_degree if in_degree[node] == 0])
    result = []

    while queue:
        node = queue.popleft()
        result.append(node)
        for neighbor in graph[node]:
            in_degree[neighbor] -= 1
            if in_degree[neighbor] == 0:
                queue.append(neighbor)
    
    return result

# 使用邻接表表示图
graph = {
    0: [1, 2],
    1: [3],
    2: [3],
    3: []
}

print(topological_sort(graph))  # 输出拓扑排序结果

3.3 判断图是否是二分图

如果一个图是二分图,那么我们可以将图中的节点分成两部分,使得每条边都连接两部分中的一个节点。可以使用 BFS 来判断图是否是二分图。

from collections import deque

def isBipartite(graph):
    color = {}
    
    def bfs(start):
        queue = deque([start])
        color[start] = 0  # 给起始节点上色
        while queue:
            node = queue.popleft()
            for neighbor in graph[node]:
                if neighbor not in color:
                    color[neighbor] = 1 - color[node]  # 给邻居节点上相反的色
                    queue.append(neighbor)
                elif color[neighbor] == color[node]:  # 如果邻居节点和当前节点同色,则不是二分图
                    return False
        return True
    
    for node in graph:
        if node not in color:
            if not bfs(node):
                return False
    
    return True

# 使用邻接表表示图
graph = {
    0: [1, 3],
    1: [0, 2],
    2: [1, 3],
    3: [0, 2]
}

print(isBipartite(graph))  # 输出是否是二分图

4. 总结:

  • 图的表示: 使用邻接矩阵适用于密集图,使用邻接表适用于稀疏图。
  • 图的遍历: 深度优先搜索(DFS)和

广度优先搜索(BFS)是图算法的基础。

  • 常见算法: 最短路径(Dijkstra),拓扑排序,判断二分图等。
  • 图的相关问题: 包括连通性、最短路径、环检测等问题。

这些是刷图类算法题时常用的语法和技巧,理解这些基础知识对解决更复杂的图问题至关重要。

标签:node,python,graph,queue,neighbor,visited,节点
From: https://www.cnblogs.com/lmc7/p/18656272

相关文章

  • python中的二叉树
    在刷算法题中,二叉树是常见的题型,掌握二叉树的基本语法和常见操作是非常重要的。以下是一些在Python中常用的二叉树语法及操作,特别是刷算法题时用到的。1.二叉树的定义:首先定义二叉树的节点结构。每个节点通常有三个属性:val(节点的值),left(左子节点),right(右子节点)。#Definitionfo......
  • 【Python基础语法——数据容器】
    python中的数据容器:一种可以容纳多份数据的数据类型,容纳的每一份数据称之为1个元素每一个元素,可以是任意类型的基本数据:数字,字符串,布尔…数据容器不同的特点:1.可否含重复元素2.可否修改3.是否有序(序号,支持下标访问)序列类型(列表,元组,字符串)一般可以下......
  • python毕设非物质文化遗产数字平台程序+论文
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、选题背景关于非物质文化遗产数字平台的研究,现有研究主要集中在非遗文化的简单数字化展示与记录方面,如建立一些静态的网页来介绍非遗项目等。专......
  • python毕设 学生考勤管理系统程序+论文
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、选题背景关于学生考勤管理系统的研究,现有研究主要以企业考勤管理系统开发为主,专门针对学校学生考勤管理系统的研究较少。在学校管理领域,考勤管......
  • 面向对象分析与设计Python版 面向对象思维
    文章目录一、面向对象思想的起源二、面向对象的基本概念三、面向对象的思考方式一、面向对象思想的起源软件人才软件人才从低到高4个成长层次:软件蓝领,软件工程师,卓越软件人才,领军人物卓越软件人才要求系统分析和设计理论基础,掌握大系统需求分析、建模与仿真技......
  • python中的链表
    在Python中,链表不是内置的数据结构,但可以通过类的方式实现自定义链表。以下是链表在刷算法题中常用的语法和操作方法。1.定义链表节点链表节点是一个包含值和指向下一个节点的指针的结构:classListNode:def__init__(self,val=0,next=None):self.val=val......
  • python中的队列
    在Python中,队列(Queue)是一种常见的数据结构,特别是在刷算法题时经常被用到。以下是队列相关的基础语法及其在算法题中的应用总结。1.队列的基本定义队列遵循FIFO(先进先出)原则,可以通过以下方式实现:1)collections.dequedeque是双端队列,支持快速的两端插入和删除操作。fro......
  • (2024最新毕设合集)基于Django的电影资讯共享平台-10223|可做计算机毕业设计JAVA、PHP、
    目录摘要Abstract1绪论1.1研究背景1.2研究意义1.3论文结构与章节安排2电影资讯共享平台系统分析2.1可行性分析2.1.1技术可行性分析2.1.2经济可行性分析2.1.3 社会可行性2.1.4法律可行性分析2.2系统功能分析2.2.1功能性分析2.2.2非功能性分析2.......
  • DL00564-图卷积神经网络GCN心电图信号ECG心律失常检测python完整代码
    图卷积神经网络(GraphConvolutionalNetwork,GCN)作为一种图神经网络(GraphNeuralNetwork,GNN)的代表,近年来在各类数据结构上表现出了优异的性能,尤其是在处理具有图结构数据时。心电图(ECG,Electrocardiogram)信号分析,特别是心律失常的检测,是医学信号处理中一个重要且挑战性的任务......
  • Python开发环境部署教程
    本教程将详细介绍如何在Windows系统上配置Python开发环境,包括安装Python、配置虚拟环境以及使用VSCode进行开发,适合新手和需要精细配置的开发者。1.安装Python1.1下载Python访问Python官网.选择最新版本的Python进行下载(建议下载64-bit版本)。1.2判断选......