第十七节:图 (20节)

一 图的概念

1)由点的集合和边的集合构成

2)虽然存在有向图和无向图的概念,但实际上都可以用有向图来表达

3)边上可能带有权值

二 图结构的表达

1)邻接表法

2)邻接矩阵法

3)除此之外还有其他众多的方式 一个边一个边的人给你

2.1 邻接表法

2.2 邻接矩阵法

面试中经常遇到的 一个一个边给你

【3,0 ,7 】 0到7 权重3

三、 图的面试题如何搞定

图的算法都不算难,只不过coding的代价比较高

1)先用自己最熟练的方式,实现图结构的表达

2)在自己熟悉的结构上,实现所有常用的图算法作为模板

3)把面试题提供的图结构转化为自己熟悉的图结构,再调用模板或改写即可

四 、图的转化器

图的转换器 GraphGenerator

4.1 代码

import java.util.HashMap;
import java.util.HashSet;
//图由点集和边集组成
public class Graph {
    //点集 整数就是当前的数值,node对应数值生成的node
    public HashMap<Integer, Node> nodes;
 //边集
    public HashSet<Edge> edges;
    
    public Graph() {
        nodes = new HashMap<>();
        edges = new HashSet<>();
    }
}

package class16;

public class Edge {
    //权重
    public int weight;
 //从哪个点
    public Node from;
 //到哪个点
    public Node to;

    public Edge(int weight, Node from, Node to) {
        this.weight = weight;
        this.from = from;
        this.to = to;
    }

}

package class16;

import java.util.ArrayList;

// 点结构的描述
public class Node {
    //当前节点的值
    public int value;
 //指向他的边
    public int in;
 //他指向的边
    public int out;
 //从他出发能找到的几点叫直接邻居
    public ArrayList<Node> nexts;
 //从他出发的边
    public ArrayList<Edge> edges;

    public Node(int value) {
        this.value = value;
        in = 0;
        out = 0;
        nexts = new ArrayList<>();
        edges = new ArrayList<>();
    }
}



public class GraphGenerator {

    // matrix 所有的边
    // N*3 的矩阵
    // [weight, from节点上面的值,to节点上面的值]
    // 
    // [ 5 , 0 , 7]
    // [ 3 , 0,  1]
    // 
 //三条边
 [
 [ 5 , 0 , 7],
 [ 5 , 0 , 7],
 [ 5 , 0 , 7]
 ]
    public static Graph createGraph(int[][] matrix) {
        Graph graph = new Graph();
        for (int i = 0; i < matrix.length; i++) {
             // 拿到每一条边, matrix[i] 
            int weight = matrix[i][0];
            int from = matrix[i][1];
            int to = matrix[i][2];
            if (!graph.nodes.containsKey(from)) {
                graph.nodes.put(from, new Node(from));
            }
            if (!graph.nodes.containsKey(to)) {
                graph.nodes.put(to, new Node(to));
            }
            Node fromNode = graph.nodes.get(from);
            Node toNode = graph.nodes.get(to);
            Edge newEdge = new Edge(weight, fromNode, toNode);
            fromNode.nexts.add(toNode);
            fromNode.out++;
            toNode.in++;
            fromNode.edges.add(newEdge);
            graph.edges.add(newEdge);
        }
        return graph;
    }

}

五、 图的宽度优先&深度优先遍历

5.1 图的宽度优先分析

描述 -宽度优先遍历

1,利用队列实现

2,从源节点开始依次按照宽度进队列,然后弹出

3,每弹出一个点,把该节点所有没有进过队列的邻接点放入队列

4,直到队列变空

为哈要加set 因为图是有回路的,如果没有set判断某个节点是否打印过,就会出现循环打印的情况,没完没了

5.2 代码

import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;

public class Code01_BFS {

    // 从node出发,进行宽度优先遍历
    public static void bfs(Node start) {
        if (start == null) {
            return;
        }
        Queue<Node> queue = new LinkedList<>();
        HashSet<Node> set = new HashSet<>();
        queue.add(start);
        set.add(start);
        while (!queue.isEmpty()) {
            Node cur = queue.poll();
            System.out.println(cur.value);
            for (Node next : cur.nexts) {
                if (!set.contains(next)) {
                    set.add(next);
                    queue.add(next);
                }
            }
        }
    }

}

import java.util.*;
class Graph {
    private int V; // 图中节点数量
    private LinkedList<Integer> adj[]; // 存储每个节点相连接的其他节点列表
    
    public Graph(int v) {
        V = v;
        adj = new LinkedList[V];
        
        for (int i=0; i < V; ++i)
            adj[i] = new LinkedList();
    }
    
    public void addEdge(int v, int w) {
        adj[v].add(w);
    }
    
    public void BFS(int s) {
        boolean visited[] = new boolean[V];
        
        Queue<Integer> queue = new LinkedList<>();
        
        visited[s]=true;
        System.out.print("BFS Traversal starting from " + s + ": ");
        queue.add(s);
        
        while (!queue.isEmpty()) {
            s = queue.poll();
            
            Iterator<Integer> i = adj[s].listIterator();
            while (i.hasNext()) {
                int n = i.next();
                
                if (!visited[n]) {
                    visited[n] = true;
                    System.out.print(n + " ");
                    queue.add(n);
                }
            }
        }
    }
}
 
public class Main {
    public static void main(String args[]) {
        Graph g = new Graph(4);
        
        g.addEdge(0, 1);
        g.addEdge(0, 2);
        g.addEdge(1, 3);
        g.addEdge(2, 3);
        
        g.BFS(0);
    }
}

5.3深度优先遍历 分析

set 打印过的节点放到set里面

描述-深度优先遍历 一条路没走完就一直走

1,利用栈实现

2,从源节点开始把节点按照深度放入栈,然后弹出

3,每弹出一个点,把该节点下一个没有进过栈的邻接点放入栈

4,直到栈变空

5.4 代码

package class16;

import java.util.HashSet;
import java.util.Stack;

public class Code02_DFS {

    public static void dfs(Node node) {
        if (node == null) {
            return;
        }
        Stack<Node> stack = new Stack<>();
        HashSet<Node> set = new HashSet<>();
        stack.add(node);
        set.add(node);
        System.out.println(node.value);
        while (!stack.isEmpty()) {
            Node cur = stack.pop();
            for (Node next : cur.nexts) {
                if (!set.contains(next)) {
                    stack.push(cur);
                    stack.push(next);
                    set.add(next);
                    System.out.println(next.value);
                    break;
                }
            }
        }
    }
    

}
   
import java.util.*;
 
class Graph {
    private int V; // 图中节点数量
    private LinkedList<Integer> adj[]; // 存储每个节点相连接的其他节点列表
    
    public Graph(int v) {
        V = v;
        adj = new LinkedList[V];
        
        for (int i=0; i<v; ++i)
            adj[i] = new LinkedList();
    }
    
    public void addEdge(int v, int w) {
        adj[v].add(w);
    }
    
    public void DFSUtil(int v, boolean visited[]) {
        visited[v] = true;
        System.out.print(v + " ");
        
        Iterator<Integer> itr = adj[v].iterator();
        while (itr.hasNext()) {
            int nbr = itr.next();
            
            if (!visited[nbr])
                DFSUtil(nbr, visited);
        }
    }
    
    public void DFSTraversal() {
        boolean[] visited = new boolean[V];
        
        for (int i=0; i<V; ++i)
            visited[i] = false;
        
        for (int i=0; i<V; ++i)
            if (!visited[i])
                DFSUtil(i, visited);
    }
}
 
public class Main {
    public static void main(String args[]) {
        Graph g = new Graph(4);
        
        g.addEdge(0, 1);
        g.addEdge(0, 2);
        g.addEdge(1, 3);
        g.addEdge(2, 3);
        
        System.out.println("DFS Traversal starting from vertex 0");
        g.DFSTraversal();
    }
} 

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第01:Axure RP7.0下载、安装、汉化与注册.flv 第02:Axure RP7.0的功能介绍(上).flv 第03: Axure RP7.0的功能介绍(下).wmv 第04: 第一个原型:简单的登录页面.wmv 第05: 第一次交互:实现跳转页面.wmv 第06:元件焦点的控制.wmv 第07:设置条件的类型.wmv 第08:设置条件的操作.wmv 第09:第一次接触动态面板.wmv 第10:元件的移动效果.flv 第11:第一次接触全局变量.flv 第12:公式的使用和局部变量简介.flv 第13:登录验证的简单实现.flv 第14:多用户登录验证的实现.flv 第15:动态面板的状态与尺寸.flv 第16:MindManager整理交互思路.flv 第17:常规思路实现注册校验.flv 第18:注册校验的另一种思路.flv 第19:通过变量进行已注册的验证.flv 第20:交互样式和选项组的设置.flv 第21:页面内多组内容切换的实现.flv 第22:文本框验证和外部url的调用.flv 第23:矩形交互样式与单选按钮组设置.flv 第24:下拉列表的交互事件.flv 第25:中继器的应用场景与结构组成.flv 第26:中继器数据的添加与删除.flv 第27:中继器数据的修改.flv 第28:中继器数据的筛选与排序.flv 第29:中继器每页项目数量与分页.flv 第30:对象、属性、函数的介绍.flv 第31:元件属性的使用(一).flv 第32:元件属性的使用(二).flv 第33:元件属性的使用(三).flv 第34:元件属性的使用(四).flv 第35:元件属性的使用(五).flv 第36:母版的介绍与使用.flv 第37:页面属性的使用.flv 第38:窗口属性与锚记.flv 第39:字符串函数(一).flv 第40:字符串函数(二).flv 第41:字符串函数(三).flv 第42:字符串函数(四).flv 第43:数学函数.flv 第44:动态面板的循环.flv 第45:日期函数.flv 第46:指针属性与动态面板拖动.flv 第47:中继器Item属性.flv 第48:中继器repeater属性.flv 第49:植入HTML和自定义元件库.flv 第50:其他补充内容(上).flv 第51:其他补充内容(下).flv 第52:原型(1)片放大效果.flv 第53:原型(2)仿真进度条效果.flv 第54:原型(3)移动端选择器.flv 第55:原型(4)Android版微信(1).flv 第56:原型(4)Android版微信(2).flv 第57:原型(4)Android版微信(3).flv 第58:原型(4)Android版微信(4).flv 第59:原型(4)Android版微信(5).flv 第60:原型(4)Android版微信(6).flv 第61:原型(5)选项添加到列表.flv 第62:原型(6)随机验证码.flv
第二 情景反应 请听句子,选出正确的答语,将其标号在答题卡上涂黑。每个句子读一遍。 6. A. In 2008 B. For 5 years C. I was in the hospital. 7. A. You’re welcome. B. I like spring . C. It’s OK. 8. A.He looked like his father . B.He looked at the door. C. He liked the songs very much. 9. A. In Shanghai B. In May C. On Sunday 10. A. Oh, it’s quick. B. I walk to school. C. Taking bus is exciting. 11. A. He likes siging . B. He is cooking C. He is an English teacher. 12. A. Great B. I went there by train. C.I’m fine. 13. A. Seven B. Four C. Twelve. 14. A. Computer games. B. The Lion King C. Table tennis. 15. A.No, you can’t B.It was too far. C. Yes, there was. 第三 对话理解 A. 请听五组对话,每组对话后您将听到一个问题,请根据对话内容选出正确答案,将其标号在答题卡上涂黑。每组对话和问题读两遍。 16. A.In England . B. In China. C.In America 17. A. 7:50 B.7:20 C. 7:10 18. A. On foot B. By bike C. By bus 19. A. His uncle B. His friends C. His parents 20. A.New York B. London C. Beijing B. 请听一段对话,对话后您将听到五个问题,请根据对话内容选出正确答案,将其标号在答题卡上涂黑。对话和问题读两遍。 21. A.In a hotel B.At the station C. At home 22. A.by train B.By plane C. By car. 23. A.Yes, he will B. We don’t know C. No, he won’t 24. A.This evening B. On Wednesday C. On Tuesday 25. A.Noodle B. Dumplings C. Hamburgers 第四 语篇理解 请仔细听短文,并根据短文内容补全以下信息,每空填一词,将单词写在答题卡上。短文读两遍。 American schools begin in September after a 26 summer vacation . Usually American children begin to go to school when 27 years old . Most students are seventeen or eighteen years old when they 28 high school. Afer high school ,many students 29 to college .(大学). So lots of students work after school to make 30 for their studies. 二、单项选择(每小题1分,共10分) 请选择最佳答案,将其标号在答题卡上涂黑。 31. _____is the population of Shanghai? A. What B. How much C. How many D. How 32. -Where is your father ? -He is at work .
Java基础教程课件 Java知识整理 1 把编写好的Java源文件保存起来,原文件的扩展名必须是_________ 用JDK编译Java源程序,使用的命令是_______,编译源¬¬¬¬文件得到字码文件。 Java源程序编译后生成的字码文件扩展名为________ 2 一个Java源程序是有若干个_____组成。_____是Java的关键字,用来定义类。 3 Java应用程序中有多个类,Java命令后的类名必须是包含了_____方法的那个类的名字。 4 一个Java应用程序必须且只有一个类含有_____方法 5 在一个Java应用程序中main方法必须被说明为_______________________ 6 Java 中所有程序都使用方法,应用程序以_______方法开始 7 Java源文件中有多个类,但只能有一个类是_________类 8 Java源程序编译后生成的字码文件扩展名为___________ 9 用来标识类名、变量名、方法名、类型名、数组名、文件名的有效字符序列称为________ 10 Java语言规定标识符由字母、下划线、美元符号和数字组成,并且第一个字符不能是__________ 11 ________就是Java语言中已经被赋予特定意义的一些单词,不可以把这类词作为名字来用 12 使用关键字_______来定义逻辑变量 13 ________就是Java语言中已经被赋予特定意义的一些单词 14 结构化程序设计的基本数据类型包括_________、__________、____________、_____________。 15 Java中byte型数组在内存中的存储形式是________ 16 对于int变量,内存分配____个字 17 对于byte变量,内存分配____个字 18 对于long变量,内存分配____个字 19 对于short变量,内存分配____个字 20 结构化程序设计的基本数据类型包括_______、逻辑类型、字符类型、浮点类型 21 使用关键字________来定义字符变量 22 结构化程序设计的基本数据类型包括_______、逻辑类型、整数类型、浮点类型 23 Java中,浮点型变量的类型有float和_________两种 24 对于float型变量,内存分配_______个字 25 对于double型变量,内存分配_______个字 26结构化程序设计的基本数据类型包括_______、逻辑类型、整数类型、字符类型 27 Java使用____________字符集 28 混合运算中不同类型的数据先转化为同一类型,然后运算,其中不包括__________和字符类型 29 混合运算中不同类型的数据先转化为同一类型,然后运算,其中不包括__________、逻辑类型 30 当把级别高的变量的值赋予级别低的变量时,必须使用______________转换 31 Java中关系运算符的运算结果是___________型 32 Java中逻辑运算符的操作元必须是________________型数据 33 整数类型数据在内存中以_______________的方式表示 34 Java语言的控制语句有3种类型,即________________、________________和转移语句 35 Java中有两种类型的控制语句即if和_______________ 36 Java语言的控制语句有3种类型,即________________、循环语句和转移语句 37 Java中的语句可分为方法______________、__________________、_________________、______________和package语句和______________语句 38 Java中的语句可分为方法调用语句、表达式语句、复合语句、控制语句、package语句和______________语句 39 在同一个switch语句中,case后的________必须互不相同. 40 do-while循环和while循环的区别是__________________________________________ 41 在循环体中,如果想结束本次循环可以用_______________语句 42 在循环体中,如果想跳出循环,结束整个循环

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值