数据结构入门-13-图

这篇具有很好参考价值的文章主要介绍了数据结构入门-13-图。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、图的概述

1.1 图论的作用

数据结构入门-13-图,Data Structure,数据结构,服务器,运维
数据结构入门-13-图,Data Structure,数据结构,服务器,运维
数据结构入门-13-图,Data Structure,数据结构,服务器,运维
数据结构入门-13-图,Data Structure,数据结构,服务器,运维
数据结构入门-13-图,Data Structure,数据结构,服务器,运维
数据结构入门-13-图,Data Structure,数据结构,服务器,运维

1.2 图的分类

数据结构入门-13-图,Data Structure,数据结构,服务器,运维
数据结构入门-13-图,Data Structure,数据结构,服务器,运维

1.2.1 无向图

数据结构入门-13-图,Data Structure,数据结构,服务器,运维

1.2.2 有向图

数据结构入门-13-图,Data Structure,数据结构,服务器,运维数据结构入门-13-图,Data Structure,数据结构,服务器,运维

1.2.3 无权图

数据结构入门-13-图,Data Structure,数据结构,服务器,运维

1.2.4 有劝图

数据结构入门-13-图,Data Structure,数据结构,服务器,运维

1.3 图的基本概念

  1. 两点相邻
  2. 点的邻边
  3. 路径Path,从一个点到另一个点走过的路
  4. 环Loop,多个点围城一个圈
  5. 自环边,自己和自己形成环
  6. 平行边,重复的边

数据结构入门-13-图,Data Structure,数据结构,服务器,运维

  1. 联通分量
    数据结构入门-13-图,Data Structure,数据结构,服务器,运维

  2. 无环图
    数据结构入门-13-图,Data Structure,数据结构,服务器,运维
    树是一种无环图,一个联通的无环图(一个联通分量)就是树

  3. 连通图的 生成树
    数据结构入门-13-图,Data Structure,数据结构,服务器,运维
    V:顶点数

数据结构入门-13-图,Data Structure,数据结构,服务器,运维
10) 顶点的度degree
顶点相邻的边数
数据结构入门-13-图,Data Structure,数据结构,服务器,运维

二、树的基本表示

2.1 邻接矩阵

数据结构入门-13-图,Data Structure,数据结构,服务器,运维
数据结构入门-13-图,Data Structure,数据结构,服务器,运维

V:顶点数,E:边数

2.1.1 邻接矩阵 表示图

import java.io.*;
import java.util.Scanner;

public class AdjMatrix {

    private int V;
    private int E;
    private int[][] adj;

    public AdjMatrix(String filename){

        File file = new File(filename);

        try(Scanner scanner = new Scanner(file)){

            V = scanner.nextInt();
            adj = new int[V][V];

            E = scanner.nextInt();
            for(int i = 0; i < E; i ++){
                int a = scanner.nextInt();
                int b = scanner.nextInt();
                adj[a][b] = 1;
                adj[b][a] = 1;
            }
        }
        catch(IOException e){
            e.printStackTrace();
        }
    }

    @Override
    public String toString(){
        StringBuilder sb = new StringBuilder();

        sb.append(String.format("V = %d, E = %d\n", V, E));
        for(int i = 0; i < V; i ++){
            for(int j = 0; j < V; j ++)
                sb.append(String.format("%d ", adj[i][j]));
            sb.append('\n');
        }
        return sb.toString();
    }

    public static void main(String[] args){

        AdjMatrix adjMatrix = new AdjMatrix("src/main/java/hGraph/base/file/g.txt");
        System.out.print(adjMatrix);
    }
}

    public int V(){
        return V;
    }

    public int E(){
        return E;
    }

//判断是否有边,两顶点是否相邻
    public boolean hasEdge(int v, int w){
        validateVertex(v);
        validateVertex(w);
        return adj[v][w] == 1;
    }
//查找和顶点v相连的顶点
    public ArrayList<Integer> adj(int v){
        validateVertex(v);
        ArrayList<Integer> res = new ArrayList<>();
        for(int i = 0; i < V; i ++)
            if(adj[v][i] == 1)
                res.add(i);
        return res;
    }
//查找顶点的度
    public int degree(int v){
        return adj(v).size();
    }

2.1.2 邻接矩阵的复杂度

数据结构入门-13-图,Data Structure,数据结构,服务器,运维

空间复杂度 可以优化,
求一个点的相邻结点 可以优化

稀疏图&稠密图
根据边的多少

完全图 每个顶点都连接

数据结构入门-13-图,Data Structure,数据结构,服务器,运维

2.2 邻接表

数据结构入门-13-图,Data Structure,数据结构,服务器,运维

2.2.1 邻接表的复杂度

数据结构入门-13-图,Data Structure,数据结构,服务器,运维
数据结构入门-13-图,Data Structure,数据结构,服务器,运维

2.2.2 邻接表By哈希表

数据结构入门-13-图,Data Structure,数据结构,服务器,运维
用红黑树实现图

import java.io.File;
import java.io.IOException;
import java.util.TreeSet;
import java.util.Scanner;

public class AdjSet {

    private int V;
    private int E;
    private TreeSet<Integer>[] adj;

    public AdjSet(String pathStr){

        File file = new File(pathStr);

        try(Scanner scanner = new Scanner(file)){

            V = scanner.nextInt();
            if(V < 0) throw new IllegalArgumentException("V must be non-negative");
            adj = new TreeSet[V];
            for(int i = 0; i < V; i ++)
                adj[i] = new TreeSet<Integer>();

            E = scanner.nextInt();
            if(E < 0) throw new IllegalArgumentException("E must be non-negative");

            for(int i = 0; i < E; i ++){
                int a = scanner.nextInt();
                validateVertex(a);
                int b = scanner.nextInt();
                validateVertex(b);

                if(a == b) throw new IllegalArgumentException("Self Loop is Detected!");
                if(adj[a].contains(b)) throw new IllegalArgumentException("Parallel Edges are Detected!");

                adj[a].add(b);
                adj[b].add(a);
            }
        }
        catch(IOException e){
            e.printStackTrace();
        }
    }

    private void validateVertex(int v){
        if(v < 0 || v >= V)
            throw new IllegalArgumentException("vertex " + v + "is invalid");
    }

    public int V(){
        return V;
    }

    public int E(){
        return E;
    }

    public boolean hasEdge(int v, int w){
        validateVertex(v);
        validateVertex(w);
        return adj[v].contains(w);
    }

    public Iterable<Integer> adj(int v){
    // public TreeSet<Integer> adj(int v){
        validateVertex(v);
        return adj[v];
    }

    public int degree(int v){
        validateVertex(v);
        return adj[v].size();
    }

    @Override
    public String toString(){
        StringBuilder sb = new StringBuilder();

        sb.append(String.format("V = %d, E = %d\n", V, E));
        for(int v = 0; v < V; v ++){
            sb.append(String.format("%d : ", v));
            for(int w : adj[v])
                sb.append(String.format("%d ", w));
            sb.append('\n');
        }
        return sb.toString();
    }

    public static void main(String[] args){

        AdjSet adjSet = new AdjSet("g.txt");
        System.out.print(adjSet);
    }
}

三、图的深度优先遍历

3.1 图深度遍历过程

之前描述过树的遍历
数据结构入门-13-图,Data Structure,数据结构,服务器,运维

数据结构入门-13-图,Data Structure,数据结构,服务器,运维

数据结构入门-13-图,Data Structure,数据结构,服务器,运维
数据结构入门-13-图,Data Structure,数据结构,服务器,运维
数据结构入门-13-图,Data Structure,数据结构,服务器,运维

    public GraphDFS(Graph G){

        this.G = G;
        visited = new boolean[G.V()];
        dfs(0);
    }

    private void dfs(int v){

        visited[v] = true;
        order.add(v);
        for(int w: G.adj(v))
            if(!visited[w])
                dfs(w);
    }

3.2 图遍历改进

数据结构入门-13-图,Data Structure,数据结构,服务器,运维

不和0 相连 的顶点,就不会遍历
原因是只针对0 调用
改进:对每一个节点进行调用
数据结构入门-13-图,Data Structure,数据结构,服务器,运维

    public GraphDFS(Graph G){

        this.G = G;
        visited = new boolean[G.V()];
        for(int v = 0; v < G.V(); v ++)
            if(!visited[v])
                dfs(v);
    }

    private void dfs(int v){

        visited[v] = true;
        pre.add(v);
        for(int w: G.adj(v))
            if(!visited[w])
                dfs(w);
        post.add(v);
    }

    public Iterable<Integer> pre(){
        return pre;
    }

    public Iterable<Integer> post(){
        return post;
    }

3.3 先中后

在树中有先中后遍历
数据结构入门-13-图,Data Structure,数据结构,服务器,运维

图也可以分为 先 后序遍历

数据结构入门-13-图,Data Structure,数据结构,服务器,运维

3.4 复杂度

遍历的复杂度:O(V+E)

四、深度遍历的应用

4.1 求联通分量

数据结构入门-13-图,Data Structure,数据结构,服务器,运维

4.2 单源路径问题

数据结构入门-13-图,Data Structure,数据结构,服务器,运维
依然做了深度优先遍历,记录这个顶点的pre:从哪里来的
单源路径:从一个顶点出发的路径,不能反向查找

import java.util.ArrayList;
import java.util.Collections;

public class SingleSourcePath {

    private Graph G;
    private int s;

    private boolean[] visited;
    private int[] pre;

    public SingleSourcePath(Graph G, int s){

        G.validateVertex(s);

        this.G = G;
        this.s = s;
        visited = new boolean[G.V()];
        pre = new int[G.V()];

        dfs(s, s);
    }

    private void dfs(int v, int parent){

        visited[v] = true;
        pre[v] = parent;
        for(int w: G.adj(v))
            if(!visited[w])
                dfs(w, v);
    }

    public boolean isConnectedTo(int t){
        G.validateVertex(t);
        return visited[t];
    }

    public Iterable<Integer> path(int t){

        ArrayList<Integer> res = new ArrayList<Integer>();
        if(!isConnectedTo(t)) return res;

        int cur = t;
        while(cur != s){
            res.add(cur);
            cur = pre[cur];
        }
        res.add(s);

        Collections.reverse(res);
        return res;
    }

    public static void main(String[] args){

        Graph g = new Graph("g.txt");
        SingleSourcePath sspath = new SingleSourcePath(g, 0);
        System.out.println("0 -> 6 : " + sspath.path(6));
        System.out.println("0 -> 5 : " + sspath.path(5));
    }
}

数据结构入门-13-图,Data Structure,数据结构,服务器,运维

4.3 检测无向图中的环

数据结构入门-13-图,Data Structure,数据结构,服务器,运维

4.4 二分图检测

二分图:
数据结构入门-13-图,Data Structure,数据结构,服务器,运维

五、图的广度优先遍历

数据结构入门-13-图,Data Structure,数据结构,服务器,运维
数据结构入门-13-图,Data Structure,数据结构,服务器,运维
数据结构入门-13-图,Data Structure,数据结构,服务器,运维

    public GraphBFS(Graph G){

        this.G = G;
        visited = new boolean[G.V()];
        for(int v = 0; v < G.V(); v ++)
            if(!visited[v])
                bfs(v);
    }

    private void bfs(int s){

        Queue<Integer> queue = new LinkedList<>();
        queue.add(s);
        visited[s] = true;
        while(!queue.isEmpty()){
            int v = queue.remove();
            order.add(v);

            for(int w: G.adj(v))
                if(!visited[w]){
                    queue.add(w);
                    visited[w] = true;
                }
        }
    }

    public Iterable<Integer> order(){
        return order;
    }

复杂度:O(V+E)

六、图论问题的建模

七、图论和AI

十一、最小生成树

11.1 带权图

数据结构入门-13-图,Data Structure,数据结构,服务器,运维

/// 暂时只支持无向带权图
public class WeightedGraph implements Cloneable{

    private int V;
    private int E;
    private TreeMap<Integer, Integer>[] adj;

    public WeightedGraph(String filename){

        File file = new File(filename);

        try(Scanner scanner = new Scanner(file)){

            V = scanner.nextInt();
            if(V < 0) throw new IllegalArgumentException("V must be non-negative");
            adj = new TreeMap[V];
            for(int i = 0; i < V; i ++)
                adj[i] = new TreeMap<Integer, Integer>();

            E = scanner.nextInt();
            if(E < 0) throw new IllegalArgumentException("E must be non-negative");

            for(int i = 0; i < E; i ++){
                int a = scanner.nextInt();
                validateVertex(a);
                int b = scanner.nextInt();
                validateVertex(b);
                int weight = scanner.nextInt();

                if(a == b) throw new IllegalArgumentException("Self Loop is Detected!");
                if(adj[a].containsKey(b)) throw new IllegalArgumentException("Parallel Edges are Detected!");

                adj[a].put(b, weight);
                adj[b].put(a, weight);
            }
        }
        catch(IOException e){
            e.printStackTrace();
        }
    }

十二、最短路径

带权图的最短路径不一定 走的边最少
数据结构入门-13-图,Data Structure,数据结构,服务器,运维

12.1 迪杰斯特拉算法

12.1.1 Dijkstra原理

  1. 指定dis:源到各个顶点的路径,先初始为MAX
    数据结构入门-13-图,Data Structure,数据结构,服务器,运维

  2. 找顶点,更新dis
    数据结构入门-13-图,Data Structure,数据结构,服务器,运维

  3. 找当前最短的路径,确定这个就是到顶点的最短路径:确定2位0到2的最短路径
    数据结构入门-13-图,Data Structure,数据结构,服务器,运维

  4. 根据2顶点,来做更新
    数据结构入门-13-图,Data Structure,数据结构,服务器,运维
    这里更新了2 到各个顶点的路径,1 从 4 更新到了3

  5. 再从当前的路径中找最小的,为3 顶点1,
    所以确定顶点1 的最短路径为3

数据结构入门-13-图,Data Structure,数据结构,服务器,运维

  1. 再根据顶点1 ,更新dis
    数据结构入门-13-图,Data Structure,数据结构,服务器,运维
  2. 确定当前最短的距离为5 ,顶点3
    数据结构入门-13-图,Data Structure,数据结构,服务器,运维
  3. 更新dis,到顶点4都为6

数据结构入门-13-图,Data Structure,数据结构,服务器,运维

每轮循环:

  1. 初始化源到其他顶点的dis,默认都为MAX
  2. 找到当前没有访问的最短路节点
  3. 确定这个节点的最短路径就是当前大小
  4. 根据这个节点的最短路径大小,更新到其他节点的路径长度,如果比dis中的要小,那么就更新dis

数据结构入门-13-图,Data Structure,数据结构,服务器,运维文章来源地址https://www.toymoban.com/news/detail-699859.html

#from ChatGPT
1.初始化距离数组dist和标记数组visited。将起始地点设置为起点,其他地点的距离初始化为无穷大,visited数组初始化为false。
2.从起点开始遍历所有地点,选择当前距离最小且未被访问过的地点u。
3.对于地点u,更新与其相邻的地点v的距离,如果新的距离小于原来的距离,则更新距离数组dist和路径数组path。
4.标记地点u为已访问,重复上述过程,直到所有地点都被访问。
5.最终得到起点到每个地点的最短距离和路径。

到了这里,关于数据结构入门-13-图的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JAVA数据结构篇--13线程安全的Set 集合

    前言:java 中用于存放不重复元素的set 集合,其中无序的HashSet,以及有序的LinkedHashSet和TreeSet 都是非线程安全的,那么多线程环境下,我们要存放不重复的元素,需要使用哪种集合进行数据存取; 1 使用: 2 过程: 2.1 放入获取元素: Collections.synchronizedSet:通过使用synchron

    2024年02月16日
    浏览(41)
  • C语言每日一题:13《数据结构》环形链表。

    题目链接: 使用快慢指针利用相对移动的思想: 1,令快指针(fast)速度为2. 2.慢指针(slow)速度为1. 3.以慢指针进入环中开始。 4。假设slow刚刚进入环中fast与它相距N。 如图所示: 1,令快指针(fast)速度为3.M 2.慢指针(slow)速度为1. 3.以慢指针进入环中开始。 4。假设slow刚

    2024年02月14日
    浏览(45)
  • 13.JavaWeb & XML:构建结构化数据的重要工具

    目录 导语: 一、XML概念 (1)可拓展 (2)功能-存储数据 (3)xml与html的区别 二、XML内容 三、XML用途 四、案例:使用XML构建在线书店的书籍数据库 结语:     在当今的信息时代,数据结构化和管理成为了一个重要课题。XML(eXtensible Markup Language,可扩展标记语言)作为一

    2024年04月09日
    浏览(49)
  • [Data structure]栈

    ⭐作者介绍:大二本科网络工程专业在读,持续学习Java,努力输出优质文章 ⭐作者主页:@逐梦苍穹 ⭐所属专栏:数据结构。数据结构专栏主要是在讲解原理的基础上拿Java实现,有时候有C/C++代码。 ⭐如果觉得文章写的不错,欢迎点个关注一键三连😉有写的不好的地方也欢

    2024年02月06日
    浏览(36)
  • 【数据结构】13:表达式转换(中缀表达式转成后缀表达式)

    从头到尾依次读取中缀表达式里的每个对象,对不同对象按照不同的情况处理。 如果遇到空格,跳过 如果遇到运算数字,直接输出 如果遇到左括号,压栈 如果遇到右括号,表示括号里的中缀表达式已经扫描完毕,将栈顶的运算符弹出并输出, 直至遇到左括号(左括号出栈

    2024年02月19日
    浏览(50)
  • 【每日算法 && 数据结构(C++)】—— 13 | 求最长自增子序列(解题思路、流程图、代码片段)

    Today’s quote is: \\\"Actions speak louder than words. 今天的一句话是:“行动胜于言辞 求最长递增子序列 最长递增子序列是指在给定序列中,找到一个最长的子序列,使得子序列中的元素按照递增的顺序排列。 例如,对于序列 [1, 3, 2, 5, 4, 7, 6],其中的最长递增子序列可以是 [1, 2, 4,

    2024年02月12日
    浏览(40)
  • R语言【base】——data.frame():创建数据框,紧耦合的变量集合,它们共享矩阵和列表的许多属性,被大多数R建模软件用作基本数据结构。

    Package  base  version 4.2.0 创建数据框(data frame),紧耦合的变量集合,它们共享矩阵和列表的许多属性,被大多数R建模软件用作基本数据结构。 数据框:一种在统计分析和数据处理中常用的数据结构,由行和列组成,类似于电子表格。 参数【...】:这些参数的形式是 value 或

    2024年02月21日
    浏览(49)
  • C++数据结构:图结构入门

    线性顺序表(数组) 线性顺序表(链表) Python风格双向链表的实现 散列表简单实现(hash表) 栈和队列的应用 二叉树之一(数组存储) 二叉树之二(二叉搜索树) 二叉树之三(二叉搜索树扩展) 图结构入门 前面系列文章介绍了线性结构和树形结构,线性结构的前驱与后续

    2024年02月07日
    浏览(38)
  • 数据结构第13周 :( 迪杰斯特拉最短路径 + 弗洛伊德求最短路径 + 欧拉回路 + Invitation Cards)

    【问题描述】 在带权有向图G中,给定一个源点v,求从v到G中的其余各顶点的最短路径问题,叫做单源点的最短路径问题。 在常用的单源点最短路径算法中,迪杰斯特拉算法是最为常用的一种,是一种按照路径长度递增的次序产生最短路径的算法。 在本题中,读入一个有向图

    2024年02月13日
    浏览(38)
  • 数据结构之堆——算法与数据结构入门笔记(六)

    本文是算法与数据结构的学习笔记第六篇,将持续更新,欢迎小伙伴们阅读学习。有不懂的或错误的地方,欢迎交流 当涉及到高效的数据存储和检索时,堆(Heap)是一种常用的数据结构。上一篇文章中介绍了树和完全二叉树,堆就是一个完全二叉树,可以分为最大堆和最小

    2024年02月11日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包