数据结构.图

本文介绍了数据结构中的图,强调了图中可能存在环的风险。图由顶点和边组成,分为有向图和无向图,以及完全图的概念。图的存储结构包括邻接矩阵和邻接链表,遍历方法包括深度优先搜索和广度优先搜索,其中BFS适用于找最短路径。
摘要由CSDN通过智能技术生成

映射数据的两种常见结构是集合和图。实现一个图来映射资源的最大风险是在图中可能有环(环指的是图的一个顶点有多条路径指向另一个顶点,这就意味着遍历图是个无止境的操作)。

                                                                                    ——《云原生基础架构.保持资源映射简单》

前言

线性结构中,除首节点没有前驱、末节点没有后继外,一个节点只有唯一的直接前驱和唯一的直接后继;树结构中,除根节点没有前驱节点外,其余的每个节点只有唯一的一个前驱(双亲)节点和多个后继(子树)节点;而在图中,任意节点间都可能有直接关系,也就是说图中一个节点的前驱和后继的数目是不限的。

图的定义

G=(V,E)

V代表图中顶点的非空有限集合,E是图中边的有限集合。

1)有向图。图中每条边都是有方向,记作<vi,vj>,表示从vi到vj有一条有向边;vi称作弧尾,vj称作弧头;

2)无向图。图中每条边都无方向,记作(vi,vj);

3)完全图。一个无向图具有n个顶点,而每个顶点与其它n-1个顶点之间都有边,则称之为无向完全图,此时其共有n(n-1)/2条边。同理n个顶点的有向完全图中边数为n(n-1),因为有向完全图每两个不同顶点之间都有两条方向相反的边;

注:任何一个顶点都可以被看作第一个顶点,巴特为了计算,给图中每个顶点赋一个序号值。

图的存储结构

1)邻接矩阵表示法

图的邻接矩阵表示法是指用一个矩阵来表示图中顶点之间的关系(相连为1,不相连为0)。对于n个顶点的图G=(V,E),其邻接矩阵是个n阶方阵:

有向图及其邻接矩阵:

        A=  \begin{bmatrix} 0 1 1 1\\ 0 0 0 0\\ 0 0 0 0\\ 1 1 0 0 \end{bmatrix}

无向图及其邻接矩阵

     B=\begin{bmatrix} 0 1 1 1\\ 1 0 0 1\\ 1 0 0 1\\ 1 1 0 0 \end{bmatrix}

2)邻接链表表示法

邻接链表表示法指的是为图的每个顶点建立一个单链表

图的遍历

基于图的每个顶点都可能与其余顶点相连,所以在遍历了某个顶点之后很可能会沿着某路径回到该顶点,这就造成了不必要的重复,那么为了避免对顶点进行重复遍历,在图的遍历过程中必须标记每个已访问过的顶点。

1,深度优先搜索(DFS)

2,广度优先搜索(BFS)

1)一度关系胜过二度关系,广度优先搜索找到的是最短的路径。一个形象例子就是你向朋友借钱,一般从关系最近的关系网开始,一旦这一层借到钱了,借钱活动结束(当然后面你要还);而一旦你的就近朋友没钱借给你,关系铁的会从他自己的朋友那里帮你筹措,也就是说你借到的钱是你朋友的朋友的钱。

算法实现(java):

public class BreadthFirstSearch {
    private static Map<String, List<String>> graph = new HashMap<>();

    private static boolean search(String name) {
        Queue<String> searchQueue = new ArrayDeque<>(graph.get(name));
        // This list is how you keep track of which people you've searched before.
        List<String> searched = new ArrayList<>();

        while (!searchQueue.isEmpty()) {
            String person = searchQueue.poll();
            // Only search this person if you haven't already searched them
            if (!searched.contains(person)) {
                if (person_is_seller(person)) {
                    System.out.println(person + " is a mango seller!");
                    return true;
                } else {
                    searchQueue.addAll(graph.get(person));
                    // Marks this person as searched
                    searched.add(person);
                }
            }
        }

        return false;
    }

    private static boolean person_is_seller(String name) {
        return name.endsWith("m");
    }

    public static void main(String[] args) {
        graph.put("you", Arrays.asList("alice", "bob", "claire"));
        graph.put("bob", Arrays.asList("anuj", "peggy"));
        graph.put("alice", Arrays.asList("peggy"));
        graph.put("claire", Arrays.asList("thom", "jonny"));
        graph.put("anuj", Collections.emptyList());
        graph.put("peggy", Collections.emptyList());
        graph.put("thom", Collections.emptyList());
        graph.put("jonny", Collections.emptyList());

        search("you");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值