图系列(一)图的表示与入度

图的表示与入度

        虽然好像没什么人看,但是我还是写一下,佛系。就当给自己做一个备忘录好了!总算,进入到图系列了。图的部分,问题很多,算法很多,应用也很广。图的两个比较重要的基石就是图的表示和图的遍历。有了这两个才能更好地搭建其他的算法。

图的表示

       我们知道G = (V, E),所以最原始的表示方式是,int n, int[][] edges。其中,n表示有n个节点,分别为{0, 1, 2, 3, ..., n-1},edges表示所有的边, edges = new int[n][2],edges[i]表示第i条边,而edges[i][0]表示起点,edges[i][1]表示终点。有关面向对象的思考: 其实可以把edges看作是一个对象数组, 每一个对象edge=edges[i], 是int[2], 包含了两个属性edge[0]和edge[1],实际上并不需要显式地进行class的定义。

邻接链表法

        本来想直接做后面的题目,但是这些基础的操作没有定义好,做后面的题目会比较麻烦。好的,我们开始介绍邻接链表的使用吧。邻接链表每一个元素是每个点相邻的点组成的链表, 比如点0与1,2,3相邻,那么0的邻接链表就是{1, 2, 3}。 下面给出代码示例。

class Solution {
    private List<Integer>[] adjs;
    public void func1(int n, int[][] edges) {
        adjs = new List[n]; // 数组初始化
        for (int i = 0 ; i < n ; i++) {
            adjs[i] = new LinkedList<>(); // 元素初始化
        }
        for (int i = 0; i < edges.length;i++) {
            int[] edge = edges[i];
            int from = edge[0];
            int to = edge[1];
            adjs[from].add(to); // 利用边元素进行初始化
            
            // 如果是无向图
            // adjs[to].add(from);
        }
    }
}

       注意,上面使用的是LinkedList,原因是: 首先, 一般遍历的时候,都是逐个遍历的,并不需要按照下标来访问元素,因此使用数组和使用链表没有区别;其次, 给链表新增元素很容易。当然,如果你知道邻接的元素不超过一定数量m时,你可以使用int[n][m+1] adjs, 其中adjs[i][0]表示stackSize, 而ajds[i][1]~adjs[i][m]是一个stack。LeetCode传送门——不邻接植花

       另外,如果需要给每条边加上weight,就需要使用对象了。

class Solution {
    private List<Node>[] adjs;
    public void func1(int n, int[][] edges) {
        adjs = new List[n]; // 数组初始化
        // 暂略
    }
    private class Node {
        public int val;
        public int weight;
        public Node(int val, int weight) {
            this.val = val;
            this.weight = weight;
        }
    }
}

邻接矩阵法

以后再写

入度

        入度的意思,也就是进入该点的边的数量。入度的用途其实蛮大的,比如找出拓扑排序中的起点,或者判断一些特殊的点。解题的时候,不妨从入度或者出度比较特殊的点开始。代码如下:

class Solution {
    public void calculateIndegree(int n, int[][] edges) {
        int[] indegrees = new int[n];
        for (int i = 0 ; i < edges.length;i++) {
            int[] edge = edges[i];
            int from = edge[0];
            int to = edge[1];
            indegrees[to] += 1;
        }
    }
}

LeetCode传送门——课程表

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值