python数据结构之图

在数学中,图是描述于一组对象的结构,其中某些对象对在某种意义上是“相关的”。这些对象对应于称为顶点的数学抽象(也称为节点或点),并且每个相关的顶点对都称为边(也称为链接或线)。通常,图形以图解形式描绘为顶点的一组点或环,并通过边的线或曲线连接。--百度百科

networkx是一个python包,用于创建、操作和研究复杂网络的结构、动态和功能。

图是一种比较复杂的数据结构,包括了一整套数学逻辑,实现起来过于复杂,还是直接用现成的networkx就好。

NetworkX提供:研究社会、生物和基础设施网络结构和动态的工具;一种适用于多种应用的标准编程接口和图形实现;为协作性、多学科项目提供快速发展环境;与现有的数值算法和C、C++和FORTRAN代码的接口;能够轻松处理大型非标准数据集。使用NetworkX,您可以以标准和非标准数据格式加载和存储网络,生成多种类型的随机和经典网络,分析网络结构,构建网络模型,设计新的网络算法,绘制网络,等等

要实现的图的边和节点示意如下,不过在实现的过程中均以无向图为主。

代码主体结构如下:

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#                     _ooOoo_
#                   o8888888o
#                    88" . "88
#                 ( | -  _  - | )
#                     O\ = /O
#                 ____/`---'\____
#                  .' \\| |// `.
#                 / \\|||:|||// \
#               / _|||||-:- |||||- \
#                | | \\\ - /// | |
#              | \_| ''\---/'' | _/ |
#               \ .-\__ `-` ___/-. /
#            ___`. .' /--.--\ `. . __
#         ."" '< `.___\_<|>_/___.' >'"".
#       | | : `- \`.;`\  _ /`;.`/ - ` : | |
#          \ \ `-. \_ __\ /__ _/ .-` / /
#      ==`-.____`-.___\_____/___.-`____.-'==
#                     `=---='
'''
@Project :pythonalgorithms 
@File :graphdatastructure.py
@Author :不胜人生一场醉
@Date :2021/7/16 22:18 
'''

import networkx as nx
import matplotlib.pyplot as plt


if __name__ == "__main__":
    testSimpleGraph()
    testGraphaddfrom()
    testGraphlabelpic()
    testGraphpospic()
    testGraphfunc()
    testGraphAlgorithms()

1、实现一个简单的无向图,并绘制出来

def testSimpleGraph():
    g = nx.Graph()  # 创建空的无向图
    # g = nx.DiGraph()  # 创建空的有向图
    g.add_node(1)
    g.add_node(2)
    g.add_node(3)
    g.add_node(4)
    g.add_edge(1, 2)
    g.add_edge(1, 3)
    g.add_edge(2, 3)
    g.add_edge(3, 4)
    nx.draw_networkx(g)
    plt.show()

结果如下:

2、通过列表实现无向图,并绘制出来:

def testGraphaddfrom():
    g = nx.Graph()  # 创建空的无向图
    g.add_nodes_from([1, 2, 3, 4, 5, 6, 7])
    g.add_edges_from([(1, 2), (1, 3), (1, 4), (1, 5), (1, 6),
                      (2, 3), (2, 4), (2, 6),
                      (3, 6),
                      (4, 5),
                      (5, 6),
                      (6, 7)])
    nx.draw_networkx(g)
    plt.show()

结果如下:

3、在图可视化中追加节点标签和边的标签

def testGraphlabelpic():
    # 数组,7个节点,13条边,有向图
    #   a   b   c   d   e   f   g
    # a     4   7   4   7   8
    # b         4   5       6
    # c         `           3
    # d                 2
    # e                     5
    # f                         8
    # g
    g = nx.Graph()
    g.add_nodes_from([
        (1, {"name": "a"}),
        (2, {"name": "b"}),
        (3, {"name": "c"}),
        (4, {"name": "d"}),
        (5, {"name": "e"}),
        (6, {"name": "f"}),
        (7, {"name": "g"}),
    ])
    g.add_edges_from([(1, 2, {'weight': 4}),
                      (1, 3, {'weight': 7}),
                      (1, 4, {'weight': 4}),
                      (1, 5, {'weight': 7}),
                      (1, 6, {'weight': 8}),
                      (2, 3, {'weight': 4}),
                      (2, 4, {'weight': 5}),
                      (2, 6, {'weight': 6}),
                      (3, 6, {'weight': 3}),
                      (4, 5, {'weight': 2}),
                      (5, 6, {'weight': 5}),
                      (6, 7, {'weight': 8})
                      ])

    pos = nx.spring_layout(g)
    # 调用draw(G, pos)将基础的点边拓扑先画出来
    nx.draw(g, pos)
    node_labels = nx.get_node_attributes(g, 'name')
    # {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f', 7: 'g'}
    # 调用draw_networkx_labels画节点标签
    nx.draw_networkx_labels(g, pos, labels=node_labels)
    edge_labels = nx.get_edge_attributes(g, 'weight')
    # {(1, 2): 4, (1, 3): 7, (1, 4): 4, (1, 5): 7, (1, 6): 8, (2, 3): 4, (2, 4): 5, (2, 6): 6, (3, 6): 3, (4, 5): 2, (5, 6): 5, (6, 7): 8}
    # 调用draw_networkx_edge_labels画和边的标签。
    nx.draw_networkx_edge_labels(g, pos, edge_labels=edge_labels)
    plt.show()

结果如下:

4、在图可视化中继续追加节点的位置和边的权重

def testGraphpospic():
    # 数组,7个节点,13条边,有向图
    #   a   b   c   d   e   f   g
    # a     4   7   4   7   8
    # b         4   5       6
    # c         `           3
    # d                 2
    # e                     5
    # f                         8
    # g
    g = nx.Graph()
    g.add_nodes_from([
        (1, {"name": "a", "pos": (3, 17), "degree": 5, "out_degree": 5, "in_degree": 0}),
        (2, {"name": "b", "pos": (1, 13), "degree": 4, "out_degree": 3, "in_degree": 1}),
        (3, {"name": "c", "pos": (2, 8), "degree": 2, "out_degree": 1, "in_degree": 1}),
        (4, {"name": "d", "pos": (5, 13), "degree": 3, "out_degree": 1, "in_degree": 2}),
        (5, {"name": "e", "pos": (7, 13), "degree": 3, "out_degree": 1, "in_degree": 2}),
        (6, {"name": "f", "pos": (5, 8), "degree": 5, "out_degree": 1, "in_degree": 4}),
        (7, {"name": "g", "pos": (7, 1), "degree": 1, "out_degree": 0, "in_degree": 1})
    ])

    g.add_edges_from([(1, 2, {'weight': 4}),
                      (1, 3, {'weight': 7}),
                      (1, 4, {'weight': 4}),
                      (1, 5, {'weight': 7}),
                      (1, 6, {'weight': 8}),
                      (2, 3, {'weight': 4}),
                      (2, 4, {'weight': 5}),
                      (2, 6, {'weight': 6}),
                      (3, 6, {'weight': 3}),
                      (4, 5, {'weight': 2}),
                      (5, 6, {'weight': 5}),
                      (6, 7, {'weight': 8})
                      ])

    # 获取节点位置
    pos = nx.get_node_attributes(g, 'pos')
    # {1: (3, 17), 2: (1, 13), 3: (2, 8), 4: (5, 13), 5: (7, 13), 6: (5, 8), 7: (7, 1)}
    # 获取节点大小值=出入度*100
    nodesize = list(nx.get_node_attributes(g, 'degree').values())
    nodesize = [i * 100 for i in nodesize]
    # 调用draw(G, pos)将基础的点边拓扑先画出来
    nx.draw(g, pos, node_size=nodesize)
    # 获取节点标签名称
    node_labels = nx.get_node_attributes(g, 'name')
    # {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f', 7: 'g'}
    # 调用draw_networkx_labels画节点标签
    nx.draw_networkx_labels(g, pos, labels=node_labels)
    # 获取边的标签名称
    edge_labels = nx.get_edge_attributes(g, 'weight')
    # {(1, 2): 4, (1, 3): 7, (1, 4): 4, (1, 5): 7, (1, 6): 8, (2, 3): 4, (2, 4): 5, (2, 6): 6, (3, 6): 3, (4, 5): 2, (5, 6): 5, (6, 7): 8}
    # 调用draw_networkx_edge_labels画和边的标签。
    nx.draw_networkx_edge_labels(g, pos, edge_labels=edge_labels)
    # 获取边的权重,即对长度进行转换
    edgewidth = list(nx.get_edge_attributes(g, 'weight').values())
    nx.draw_networkx_edges(g, pos, width=edgewidth)
    plt.show()

6、测试networkx中关于日常操作的基本函数

def testGraphfunc():
    # 数组,7个节点,13条边,有向图
    #   a   b   c   d   e   f   g
    # a     4   7   4   7   8
    # b         4   5       6
    # c         `           3
    # d                 2
    # e                     5
    # f                         8
    # g
    # 判断两节点间是否有边    Graph.has_edge(u, v)
    # 网络中结点的个数  G.number_of_nodes()
    # 网络中边的个数   G.number_of_edges()
    # 获取结点i的邻居节点    G.neighbors(i)  或   G[i](在有向图中输出的是出度的邻居,G[i]会输出权重)
    # 获取所有节点的度  G.degree()
    # 获取节点i的属性  G.nodes[i]["wight"]
    # 查看图中所有点的信息    G.nodes.data()
    g = nx.Graph()
    g.add_nodes_from([
        (1, {"name": "a", "pos": (3, 17), "degree": 5, "out_degree": 5, "in_degree": 0, "wight": 5}),
        (2, {"name": "b", "pos": (1, 13), "degree": 4, "out_degree": 3, "in_degree": 1}),
        (3, {"name": "c", "pos": (2, 8), "degree": 2, "out_degree": 1, "in_degree": 1}),
        (4, {"name": "d", "pos": (5, 13), "degree": 3, "out_degree": 1, "in_degree": 2}),
        (5, {"name": "e", "pos": (7, 13), "degree": 3, "out_degree": 1, "in_degree": 2}),
        (6, {"name": "f", "pos": (5, 8), "degree": 5, "out_degree": 1, "in_degree": 4}),
        (7, {"name": "g", "pos": (7, 1), "degree": 1, "out_degree": 0, "in_degree": 1})
    ])

    g.add_edges_from([(1, 2, {'weight': 4}),
                      (1, 3, {'weight': 7}),
                      (1, 4, {'weight': 4}),
                      (1, 5, {'weight': 7}),
                      (1, 6, {'weight': 8}),
                      (2, 3, {'weight': 4}),
                      (2, 4, {'weight': 5}),
                      (2, 6, {'weight': 6}),
                      (3, 6, {'weight': 3}),
                      (4, 5, {'weight': 2}),
                      (5, 6, {'weight': 5}),
                      (6, 7, {'weight': 8})
                      ])
    # 判断两节点间是否有边    Graph.has_edge(u, v)
    print('节点2和节点4是否有边=', g.has_edge(2, 4))  # True
    print('节点3和节点4是否有边=', g.has_edge(3, 4))  # False
    # 网络中结点的个数  G.number_of_nodes()
    print('网络中结点的个数=', g.number_of_nodes())  # 7
    # 网络中边的个数   G.number_of_edges()
    print('网络中边的个数=', g.number_of_edges())  # 12
    # 获取结点i的邻居节点    G.neighbors(i)
    print('获取结点1的邻居节点=', g.neighbors(1))
    # 获取结点1的邻居节点= <dict_keyiterator object at 0x00000261558B2D10>
    print('获取结点1的邻居节点=', list(g.neighbors(1)))
    # 获取结点1的邻居节点= [2, 3, 4, 5, 6]
    # 获取所有节点的度  G.degree()
    print('获取所有节点的度=', g.degree())
    # 获取所有节点的度= [(1, 5), (2, 4), (3, 3), (4, 3), (5, 3), (6, 5), (7, 1)]
    # 获取节点i G.nodes[i]
    print('获取节点i=', g.nodes[1])
    # 获取节点i= {'name': 'a', 'pos': (3, 17), 'degree': 5, 'out_degree': 5, 'in_degree': 0, 'wight': 5}
    # 获取节点i的属性名 G.nodes[i]
    print('获取节点i的属性名=', list(g.nodes[1]))
    # 获取节点i= ['name', 'pos', 'degree', 'out_degree', 'in_degree', 'wight']
    # 获取节点i的属性值 = 5
    # 获取节点i的属性值 G.nodes[i]["wight"]
    print('获取节点i的属性值=', g.nodes[1]["wight"])
    # 获取节点i的属性 = 5
    # 查看图中所有点的信息    G.nodes.data()
    print('查看图中所有点的信息=', g.nodes.data())

    # 查看图中所有点的信息= [
    # (1, {'name': 'a', 'pos': (3, 17), 'degree': 5, 'out_degree': 5, 'in_degree': 0, 'wight': 5}),
    # (2, {'name': 'b', 'pos': (1, 13), 'degree': 4, 'out_degree': 3, 'in_degree': 1}),
    # (3, {'name': 'c', 'pos': (2, 8), 'degree': 2, 'out_degree': 1, 'in_degree': 1}),
    # (4, {'name': 'd', 'pos': (5, 13), 'degree': 3, 'out_degree': 1, 'in_degree': 2}),
    # (5, {'name': 'e', 'pos': (7, 13), 'degree': 3, 'out_degree': 1, 'in_degree': 2}),
    # (6, {'name': 'f', 'pos': (5, 8), 'degree': 5, 'out_degree': 1, 'in_degree': 4}),
    # (7, {'name': 'g', 'pos': (7, 1), 'degree': 1, 'out_degree': 0, 'in_degree': 1})]

结果如下:

节点2和节点4是否有边= True
节点3和节点4是否有边= False
网络中结点的个数= 7
网络中边的个数= 12
获取结点1的邻居节点= <dict_keyiterator object at 0x0000026FA0EC27C0>
获取结点1的邻居节点= [2, 3, 4, 5, 6]
获取所有节点的度= [(1, 5), (2, 4), (3, 3), (4, 3), (5, 3), (6, 5), (7, 1)]
获取节点i= {'name': 'a', 'pos': (3, 17), 'degree': 5, 'out_degree': 5, 'in_degree': 0, 'wight': 5}
获取节点i的属性名= ['name', 'pos', 'degree', 'out_degree', 'in_degree', 'wight']
获取节点i的属性值= 5
查看图中所有点的信息= [(1, {'name': 'a', 'pos': (3, 17), 'degree': 5, 'out_degree': 5, 'in_degree': 0, 'wight': 5}), (2, {'name': 'b', 'pos': (1, 13), 'degree': 4, 'out_degree': 3, 'in_degree': 1}), (3, {'name': 'c', 'pos': (2, 8), 'degree': 2, 'out_degree': 1, 'in_degree': 1}), (4, {'name': 'd', 'pos': (5, 13), 'degree': 3, 'out_degree': 1, 'in_degree': 2}), (5, {'name': 'e', 'pos': (7, 13), 'degree': 3, 'out_degree': 1, 'in_degree': 2}), (6, {'name': 'f', 'pos': (5, 8), 'degree': 5, 'out_degree': 1, 'in_degree': 4}), (7, {'name': 'g', 'pos': (7, 1), 'degree': 1, 'out_degree': 0, 'in_degree': 1})]
[(1, 2, {'weight': 4}), (1, 4, {'weight': 4}), (2, 3, {'weight': 4}), (3, 6, {'weight': 3}), (4, 5, {'weight': 2}), (6, 7, {'weight': 8})]
节点1-节点7最短路径= [1, 6, 7]

7、测试networkx中关于最短路径、连通性、各种遍历等算法功能:

def testGraphAlgorithms():
    # 数组,7个节点,13条边,有向图
    #   a   b   c   d   e   f   g
    # a     4   7   4   7   8
    # b         4   5       6
    # c         `           3
    # d                 2
    # e                     5
    # f                         8
    # g
    g = nx.Graph()
    g.add_nodes_from([
        (1, {"name": "a", "pos": (3, 17), "degree": 5, "out_degree": 5, "in_degree": 0, "wight": 5}),
        (2, {"name": "b", "pos": (1, 13), "degree": 4, "out_degree": 3, "in_degree": 1}),
        (3, {"name": "c", "pos": (2, 8), "degree": 2, "out_degree": 1, "in_degree": 1}),
        (4, {"name": "d", "pos": (5, 13), "degree": 3, "out_degree": 1, "in_degree": 2}),
        (5, {"name": "e", "pos": (7, 13), "degree": 3, "out_degree": 1, "in_degree": 2}),
        (6, {"name": "f", "pos": (5, 8), "degree": 5, "out_degree": 1, "in_degree": 4}),
        (7, {"name": "g", "pos": (7, 1), "degree": 1, "out_degree": 0, "in_degree": 1})
    ])

    g.add_edges_from([(1, 2, {'weight': 4}),
                      (1, 3, {'weight': 7}),
                      (1, 4, {'weight': 4}),
                      (1, 5, {'weight': 7}),
                      (1, 6, {'weight': 8}),
                      (2, 3, {'weight': 4}),
                      (2, 4, {'weight': 5}),
                      (2, 6, {'weight': 6}),
                      (3, 6, {'weight': 3}),
                      (4, 5, {'weight': 2}),
                      (5, 6, {'weight': 5}),
                      (6, 7, {'weight': 8})
                      ])

    # 最小生成树
    tree = nx.minimum_spanning_tree(g, algorithm='prim')
    print(tree.edges(data=True))
    # [(1, 2, {'weight': 4}),
    # (1, 4, {'weight': 4}),
    # (2, 3, {'weight': 4}),
    # (3, 6, {'weight': 3}),
    # (4, 5, {'weight': 2}),
    # (6, 7, {'weight': 8})]

    # 最短路径
    print("节点1-节点7最短路径=",nx.dijkstra_path(g, 1, 7))
    # [1, 6, 7]
    # 所有节点之间的最短路径
    gen = nx.all_pairs_shortest_path(g)
    print("所有节点之间的最短路径=",dict(gen))
    # {
    # 1: {1: [1], 2: [1, 2], 3: [1, 3], 4: [1, 4], 5: [1, 5], 6: [1, 6], 7: [1, 6, 7]},
    # 2: {2: [2], 1: [2, 1], 3: [2, 3], 4: [2, 4], 6: [2, 6], 5: [2, 1, 5], 7: [2, 6, 7]},
    # 3: {3: [3], 1: [3, 1], 2: [3, 2], 6: [3, 6], 4: [3, 1, 4], 5: [3, 1, 5], 7: [3, 6, 7]},
    # 4: {4: [4], 1: [4, 1], 2: [4, 2], 5: [4, 5], 3: [4, 1, 3], 6: [4, 1, 6], 7: [4, 1, 6, 7]},
    # 5: {5: [5], 1: [5, 1], 4: [5, 4], 6: [5, 6], 2: [5, 1, 2], 3: [5, 1, 3], 7: [5, 6, 7]},
    # 6: {6: [6], 1: [6, 1], 2: [6, 2], 3: [6, 3], 5: [6, 5], 7: [6, 7], 4: [6, 1, 4]},
    # 7: {7: [7], 6: [7, 6], 1: [7, 6, 1], 2: [7, 6, 2], 3: [7, 6, 3], 5: [7, 6, 5], 4: [7, 6, 1, 4]}}

    print("各点之间可达性=",nx.communicability(g))
    # 各点之间可达性= {
    # 1: {1: 11.66037697759954, 2: 9.730688193140374, 3: 8.180239781697592, 4: 7.645194148638486, 5: 7.720951055876168, 6: 10.188202427433492, 7: 2.4556767248680185},
    # 2: {1: 9.730688193140374, 2: 8.966431076518731, 3: 7.2767859598006615, 4: 6.497877866101427, 5: 6.132652147982442, 6: 8.800266284965774, 7: 2.136327166832645},
    # 3: {1: 8.180239781697592, 2: 7.2767859598006615, 3: 6.750798019391801, 4: 4.922928096425332, 5: 4.985335865445396, 6: 7.643419657110174, 7: 1.9072819535912968},
    # 4: {1: 7.645194148638486, 2: 6.497877866101427, 3: 4.922928096425332, 4: 5.962359580374006, 5: 5.4295610915115375, 6: 6.2992895922037295, 7: 1.3858918410969554},
    # 5: {1: 7.720951055876168, 2: 6.132652147982442, 3: 4.985335865445396, 4: 5.4295610915115375, 5: 6.053240117357615, 6: 6.892984331374484, 7: 1.7072857005030746},
    # 6: {1: 10.188202427433492, 2: 8.800266284965774, 3: 7.643419657110174, 4: 6.2992895922037295, 5: 6.892984331374484, 6: 10.11197286752748, 7: 3.0514157654095175},
    # 7: {1: 2.4556767248680185, 2: 2.136327166832645, 3: 1.9072819535912968, 4: 1.3858918410969554, 5: 1.7072857005030746, 6: 3.0514157654095175, 7: 1.9054013217324557}}


    print("获得图中非连通点的列表=",list(nx.isolates(g)))
    # 获得图中非连通点的列表 = []
    g.add_node(8)
    print("获得图中非连通点的列表=", list(nx.isolates(g)))
    # 获得图中非连通点的列表= [8]

    # 遍历
    d_gen = nx.dfs_edges(g, 1)  # 按边深度搜索, 1为起点
    b_gen = nx.bfs_edges(g, 1)
    print("深度搜索:",list(d_gen))
    # [(1, 2), (2, 3), (3, 6), (6, 5), (5, 4), (6, 7)]
    print("广度搜索:",list(b_gen))
    # [(1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (6, 7)]
    print(nx.dfs_tree(g, 1).nodes())  # 按点深搜g
    # [1, 2, 3, 6, 5, 4, 7]
    print("先序遍历:", list(nx.dfs_preorder_nodes(g, 1)))
    # 先序遍历: [1, 2, 3, 6, 5, 4, 7]
    print("后序遍历:", list(nx.dfs_postorder_nodes(g, 1)))
    # 后序遍历: [4, 5, 7, 6, 3, 2, 1]
    print("节点1和节点2的共同邻居:", list(nx.common_neighbors(g, 1, 2)))
    # 节点0和节点33的共同邻居: [3, 4, 6]
    print("节点1和节点7的共同邻居:", list(nx.common_neighbors(g, 1, 7)))
    # 节点0和节点33的共同邻居: [6]

结果如下:


所有节点之间的最短路径= {1: {1: [1], 2: [1, 2], 3: [1, 3], 4: [1, 4], 5: [1, 5], 6: [1, 6], 7: [1, 6, 7]}, 2: {2: [2], 1: [2, 1], 3: [2, 3], 4: [2, 4], 6: [2, 6], 5: [2, 1, 5], 7: [2, 6, 7]}, 3: {3: [3], 1: [3, 1], 2: [3, 2], 6: [3, 6], 4: [3, 1, 4], 5: [3, 1, 5], 7: [3, 6, 7]}, 4: {4: [4], 1: [4, 1], 2: [4, 2], 5: [4, 5], 3: [4, 1, 3], 6: [4, 1, 6], 7: [4, 1, 6, 7]}, 5: {5: [5], 1: [5, 1], 4: [5, 4], 6: [5, 6], 2: [5, 1, 2], 3: [5, 1, 3], 7: [5, 6, 7]}, 6: {6: [6], 1: [6, 1], 2: [6, 2], 3: [6, 3], 5: [6, 5], 7: [6, 7], 4: [6, 1, 4]}, 7: {7: [7], 6: [7, 6], 1: [7, 6, 1], 2: [7, 6, 2], 3: [7, 6, 3], 5: [7, 6, 5], 4: [7, 6, 1, 4]}}
各点之间可达性= {1: {1: 11.66037697759954, 2: 9.730688193140374, 3: 8.180239781697592, 4: 7.645194148638486, 5: 7.720951055876168, 6: 10.188202427433492, 7: 2.4556767248680185}, 2: {1: 9.730688193140374, 2: 8.966431076518731, 3: 7.2767859598006615, 4: 6.497877866101427, 5: 6.132652147982442, 6: 8.800266284965774, 7: 2.136327166832645}, 3: {1: 8.180239781697592, 2: 7.2767859598006615, 3: 6.750798019391801, 4: 4.922928096425332, 5: 4.985335865445396, 6: 7.643419657110174, 7: 1.9072819535912968}, 4: {1: 7.645194148638486, 2: 6.497877866101427, 3: 4.922928096425332, 4: 5.962359580374006, 5: 5.4295610915115375, 6: 6.2992895922037295, 7: 1.3858918410969554}, 5: {1: 7.720951055876168, 2: 6.132652147982442, 3: 4.985335865445396, 4: 5.4295610915115375, 5: 6.053240117357615, 6: 6.892984331374484, 7: 1.7072857005030746}, 6: {1: 10.188202427433492, 2: 8.800266284965774, 3: 7.643419657110174, 4: 6.2992895922037295, 5: 6.892984331374484, 6: 10.11197286752748, 7: 3.0514157654095175}, 7: {1: 2.4556767248680185, 2: 2.136327166832645, 3: 1.9072819535912968, 4: 1.3858918410969554, 5: 1.7072857005030746, 6: 3.0514157654095175, 7: 1.9054013217324557}}
获得图中非连通点的列表= []
获得图中非连通点的列表= [8]
深度搜索: [(1, 2), (2, 3), (3, 6), (6, 5), (5, 4), (6, 7)]
广度搜索: [(1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (6, 7)]
[1, 2, 3, 6, 5, 4, 7]
先序遍历: [1, 2, 3, 6, 5, 4, 7]
后序遍历: [4, 5, 7, 6, 3, 2, 1]
节点1和节点2的共同邻居: [3, 4, 6]
节点1和节点7的共同邻居: [6]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

python与大数据分析

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

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

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

打赏作者

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

抵扣说明:

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

余额充值