纸上谈兵: 图 (graph)

  • 时间:
  • 浏览:1
  • 来源:幸运快3_快3平台代理_幸运快3平台代理

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!

图(graph)是两种比较松散的数据型态。它有其他节点(vertice),在其他节点之间,由(edge)相连。节点的概念在树中也跳出过,朋友通常在节点中储存数据。边表示有一一两个 节点之间的占据 关系。在树中,朋友用边来表示子节点和父节点的归属关系。树是两种特殊的图,但限制性更强其他。

其他 的两种数据型态是很常见的。比如计算机网络,其他 由其他节点(计算机怎么让路由器)以及节点之间的边(网线)构成的。城市的道路系统,也是由节点(路口)和边(道路)构成的图。地铁系统不能没办法 理解为图,地铁站能没办法 认为是节点。基于图有其他经典的算法,比如求图中有 一一两个 节点的最短路径,求最小伸展树等。

图的经典研究是柯尼斯堡七桥问题图片(Seven Bridges of Königsberg)。柯尼斯堡是现今的加里宁格勒,城市中有 一条河流过,河中有 有一一两个 小岛。有七座桥桥连接河的两岸和有一一两个 小岛。送信员总想知道,有没办法 一有一一两个 办法,能不重复的走过7个桥呢?

(你你你你這個问题图片在其他奥数教材中称为"一笔画"问题图片)

欧拉时代的柯尼斯堡地图

柯尼斯堡的能没办法 看作由7个边和有一一两个 节点构成的一有一一两个 图:

你你你你這個问题图片最终被欧拉巧妙的处理。七桥问题图片也启发了一门新的数科学数学科——图论(graph theory)的诞生。欧拉的基本思路是,怎么让某个节点也有起点怎么让终点,没办法 连接它的边的数目需要为偶数个(从一有一一两个 桥进入,再从其他 桥离开)。对于柯尼斯堡的七桥,怎么让有一一两个 节点都为奇数个桥,而最多没办法 有有一一两个 节点为起点和终点,其他不怎么让一次走完。

图的定义

严格的说,图[$G = (V, E)$]是由节点的集合V和边的集合E构成的。一有一一两个 图的所有节点构成一有一一两个 集合[$V$]。一有一一两个 边能没办法 表示为[$(v_1, v_2)$],其中[$v_1, v_2 \in V$],即有一一两个 节点。怎么让[$(v_1, v_2)$]有序,即[$(v_1, v_2)$]与[$(v_2, v_1)$]不同,没办法 图是有向的(directed)。有序的边能没办法 理解为单行道,没办法 沿一有一一两个 方向行进。怎么让[$(v_1, v_2)$]无序,没办法 图是无向的(undirected)。无序的边能没办法 理解成双向都能没办法 行进的道路。一有一一两个 无序的边能没办法 看作连接相同节点的有一一两个 反向的有序边,其他无向图能没办法 理解为有向图的两种特殊情况表。

(七桥问题图片中的图是无向的。城市中的公交线路能没办法 是无向的,比如占据 单向环线)

图的一有一一两个 路径(path)是图的一系列节点[$w_1, w_2, ..., w_n$],且对于[$1 \le i < n $],有[$ (w_i, w_{i+1}) \in E$]。也其他 说,路径是一系列的边连接而成,路径的两端为有一一两个 节点。路径上面的总数称为路径的长度。乘坐地铁时,朋友会在挑选某个路径,来从A站到达B站。其他 的路径怎么让有不止一条,朋友往往会根据路径的长度以及沿线的拥挤情况表,来挑选一条最佳的路线。怎么让占据 一条长度大于0的路径,该路径的两端为同一节点,没办法 认为该图中占据 环路(cycle)。很明显,上海的地铁系统中占据 环路。

 

找到一条环路

怎么让从每个节点,到任意一有一一两个 其它的节点,也有一条路径的话,没办法 图是连通的(connected)。对于一有一一两个 有向图来说,其他 的连通称为强连通(strongly connected)。怎么让一有一一两个 有向图不满足强连通的条件,但将它的所有边都改为双向的,此时的无向图是连通的,没办法 认为该有向图是弱连通(weakly connected)。

怎么让将有火车站的城市认为是节点,铁路是连接城市的边,其他 的图怎么让是不连通的。比如北京和费城,北京有铁路通往上海,费城有铁路通往纽约,但北京和费城之间没办法 路径相连。

图的实现

两种简单的实现图的办法是使用二维数组。让数组a的每一行为一有一一两个 节点,该行的不同元素表示该节点与其他节点的连接关系。怎么让[$(u, v) \in E$],没办法 a[u][v]记为1,怎么让为0。比如下面的一有一一两个 包中有 一一两个 节点的图:

 

能没办法 简单表示为

a 1 2 3
1 0 1 1
2 0 0 0
3 0 1 0

你你你你這個实现办法所占据 的空间为[$O(|V|^2)$],[$|V|$]为节点总数。所需内存随着节点增加而飞快增多。怎么让边也有很密集,没办法 其他数组元素记为0,没办法 稀疏的其他数组元素记为1,其他并也有很经济。

更经济的实现办法是使用,即记录每个节点所有的相邻节点。对于节点m,朋友建立一有一一两个 链表。对于任意节点k,怎么让有[$(m, k) \in E$],就将该节点装入到对应节点m的链表中。邻接表是实现图的标准办法。比如下面的图,

 

能没办法 用如下的数据型态实现:

 

左侧为一有一一两个 数组,每个数组元素代表一有一一两个 节点,且指向一有一一两个 链表。该链表包中有 该数组元素所有的相邻元素。

总体上看,邻接表能没办法 分为两每种。邻接表所占据 的总空间为[$O(|V| + |E|)$]。数组每种储存节点信息,占据 [$|V|$])的空间,即节点的总数。链表存储边的信息,占据 [$|E|$]的空间,即边的总数。在其他冗杂的问题图片中,定点和边还怎么让有其他的附加信息,朋友能没办法 将那些附加信息储占据 相应的节点怎么让边的位置。

下面为具体的C代码:

/* By Vamei */
#include <stdio.h>
#include <stdlib.h>

#define NUM_V 5

typedef struct node *position;

/* node */
struct node {
    int element;
    position next;
};

/* 
 * operations (stereotype)
 */
void insert_edge(position, int, int);
void print_graph(position graph, int nv);

/* for testing purpose */
void main()
{
    struct node graph[NUM_V];
    int i;

    // initialize the vertices
    for(i=1; i<NUM_V; i++) {
        (graph+i)->element = i;
        (graph+i)->next    = NULL;
    }

    // insert edges
    insert_edge(graph,1,2);
    insert_edge(graph,1,4);
    insert_edge(graph,3,2);
    insert_edge(graph,4,2);
    insert_edge(graph,4,3);

    print_graph(graph,NUM_V);
}

/* print the graph */
void print_graph(position graph, int nv) {
    int i;
    position p;
    for(i=1; i<nv; i++) {
        p = (graph + i)->next;
        printf("From %3d: ", i);
        while(p != NULL) {
            printf("%d->%d; ", i, p->element);
            p = p->next;
        }
        printf("\n");
    }
}

/*
 * insert an edge
 */
void insert_edge(position graph,int from, int to)
{
    position np;
    position nodeAddr;

    np = graph + from;

    nodeAddr = (position) malloc(sizeof(struct node));
    nodeAddr->element = to;
    nodeAddr->next    = np->next;
    np->next = nodeAddr;
}

运行结果:

From   1: 1->4; 1->2;

From   2:

From   3: 3->2;

From   4: 4->3; 4->2;

上面的实现主要基于链表,可参考纸上谈兵: 表 (list) 。

总结

图是两种很简单的数据型态。图的组织办法比较松散,自由度比较大,但也造成比较高的算法冗杂度。我将在并且介绍其他图的经典算法。

欢迎继续阅读“纸上谈兵: 算法与数据型态”系列

猜你喜欢

ST拉万特河谷新闻,ST拉万特河谷赛程赛果,ST拉万特河谷数据统计,ST拉万特河谷阵容,ST拉万特河谷球员名单

首页新闻视频直播数据APP懂球号直播君广告企业企业合作ST拉万特河谷St.Michael/Lavanttal成立:国家:城市:主场:容纳:人电话:邮箱:地址:赛程<前10

2020-01-23

对话阿里张勇:双11不为交易数字,我十年从不做预期

阿里巴巴天猫双11于今日夜里正式打响。晚上22点28分,成交额突破1150亿元。与此同時 ,阿里巴巴CEO张勇接受了新浪科技采访。张勇指出,双11所以我走过10年,他对总交易

2020-01-23

V. Kernstock数据,V. Kernstock新闻,V. Kernstock视频,V. Kernstock身价

V.KernstockV.Kernstock俱乐部:特尔福斯国籍:奥地利身高:CM位置:前锋年龄:17岁体重:KG号码:号生日:5002-08-06惯用脚:相关队员前锋进球国籍

2020-01-23

上线送满v传奇游戏盒子最新下载

上线送满v传奇游戏盒子是一款最新好玩的游戏软件平台,由创游科技倾力打造的游戏下载应用平台,在这里我就到最新、最火爆的BT游戏,然后上线即送满VIP、免费0元GM特权服,豪华游戏

2020-01-23

古代文人多有雅号,而原因固不止一端!

核心提示:古代文人多有雅号,而雅号的得名,因为着固不止一端。有因所从事的职业而得名的。计有功在《唐诗纪事》中说,胡令能“少为负局钉铰之业”,也否则 否则 用铆钉把破损的锅碗

2020-01-23