惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

AI
AI
博客园 - 叶小钗
Blog — PlanetScale
Blog — PlanetScale
Microsoft Azure Blog
Microsoft Azure Blog
Vercel News
Vercel News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
MyScale Blog
MyScale Blog
大猫的无限游戏
大猫的无限游戏
A
About on SuperTechFans
量子位
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 【当耐特】
Martin Fowler
Martin Fowler
阮一峰的网络日志
阮一峰的网络日志
D
Docker
Jina AI
Jina AI
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
The Register - Security
The Register - Security
J
Java Code Geeks
S
SegmentFault 最新的问题
月光博客
月光博客
G
Google Developers Blog
美团技术团队
Last Week in AI
Last Week in AI
L
LangChain Blog
Apple Machine Learning Research
Apple Machine Learning Research
T
The Blog of Author Tim Ferriss
腾讯CDC
Recent Announcements
Recent Announcements
Recorded Future
Recorded Future
The Cloudflare Blog
有赞技术团队
有赞技术团队
博客园_首页
博客园 - 聂微东
人人都是产品经理
人人都是产品经理
B
Blog
I
InfoQ
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
F
Fortinet All Blogs
B
Blog RSS Feed
Engineering at Meta
Engineering at Meta
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Microsoft Security Blog
Microsoft Security Blog
MongoDB | Blog
MongoDB | Blog
爱范儿
爱范儿
D
DataBreaches.Net
F
Full Disclosure
M
MIT News - Artificial intelligence
博客园 - 司徒正美
H
Help Net Security

青空之蓝

[青空之蓝-2023] - 色彩 | 青空之蓝 [青空之蓝-2022] - 平静 | 青空之蓝 [青空之蓝-2021] - 远望 | 青空之蓝 浅谈垃圾回收 | 青空之蓝 浅谈泛型擦除 | 青空之蓝 浅谈单点登录 | 青空之蓝 使用 Kotlin 编写 Spring 测试 | 青空之蓝 设计模式系列文章 | 青空之蓝 从零实现一个 Java 微框架 - IoC | 青空之蓝 从零实现一个 Java 微框架 - 前言 | 青空之蓝 浅谈 JVM:类加载 | 青空之蓝 浅谈 IO | 青空之蓝 浅谈并发:synchronized & ReentrantLock | 青空之蓝 浅谈并发:CAS & AQS | 青空之蓝 浅谈并发:ThreadLocal | 青空之蓝 浅谈并发:三大特性 | 青空之蓝 浅谈组合注解 & 注解别名 | 青空之蓝 [青空之蓝-2020]-迷茫 | 青空之蓝 Java 系列文章 | 青空之蓝 HTTP 系列文章 | 青空之蓝 浅谈 EatWhatYouKill | 青空之蓝 浅谈可扩展线程池 | 青空之蓝 聊聊写框架 | 青空之蓝 聊聊现状-[2020-09] | 青空之蓝 浅谈并发:锁 | 青空之蓝 浅谈并发:基础 | 青空之蓝 浅谈缓存 | 青空之蓝 无须定义类,Spring 快速注入 Json 参数 | 青空之蓝 浅谈 Proxy 和 Aop | 青空之蓝 从零实现一个 PHP 微框架 - 初始化请求 | 青空之蓝 为 Vue3 添加一个简单的 Store | 青空之蓝 从零实现一个 PHP 微框架 - 服务提供者 | 青空之蓝 WSL2 踩坑记录 | 青空之蓝 浅谈浏览器Event Loop [更新] | 青空之蓝 从零实现一个 PHP 微框架 - Bootstrap 启动加载 | 青空之蓝 从零实现一个 PHP 微框架 - IoC 容器 | 青空之蓝 从零实现一个 PHP 微框架 - PSR & Composer | 青空之蓝 从零实现一个 PHP 微框架 - 前言 | 青空之蓝 MVVM 简单实现 | 青空之蓝 浅谈 DI 和 IoC | 青空之蓝 中间件实现 [PHP] | 青空之蓝 告别 Windows 终端的难看难用,打造好用的 PowerShell | 青空之蓝 VSCode Java输出中文乱码问题解决[更新] | 青空之蓝 浅谈浏览器渲染 | 青空之蓝 Vue-Cli@2 项目迁移日志 | 青空之蓝 Laragon & Scoop 集成踩坑记录 | 青空之蓝 「一行代码」优雅管理 Windows 软件 | 青空之蓝 [青空之蓝-2019]-年度总结 | 青空之蓝 为Vue添加简单的Store | 青空之蓝 为React添加简单的Store | 青空之蓝 为Vuex添加同步Action | 青空之蓝 浅谈B+树 | 青空之蓝 浅谈跳表 | 青空之蓝 浅谈数据库索引 | 青空之蓝 MySQL事务隔离 | 青空之蓝 算法复杂度分析(1) | 青空之蓝 一年来的经验总结 | 青空之蓝 Acrylic - VSCode Extension | 青空之蓝 ace编辑器设置惯性滚动 | 青空之蓝 Java二叉树实现 | 青空之蓝 为apt方式安装的nginx重新编译增加WebDAV | 青空之蓝 XK-Editor - 一个支持富文本和Markdown的编辑器 | 青空之蓝 JS生成列表树 | 青空之蓝 Laravel生成目录树 | 青空之蓝 XK-Note - 集各种神奇功能的云笔记 | 青空之蓝 PHP GD生成验证码 | 青空之蓝 PHP GD图片处理[转换格式-水印-缩略图] | 青空之蓝 Origami - 简洁轻快的WordPress主题 | 青空之蓝 为WordPress启用WorkBox | 青空之蓝 [青空之蓝-2018]-年度总结 | 青空之蓝 VSCode Java手动导入jar和源码包 | 青空之蓝 Windows IP变化自动发送邮件 | 青空之蓝 C链表实现重制版 | 青空之蓝 C 结构体的定义和使用 | 青空之蓝 图的搜索(遍历) - BFS & DFS | 青空之蓝 Java链表实现 | 青空之蓝 C 快速排序 | 青空之蓝 C 插入排序 | 青空之蓝 C 归并排序 | 青空之蓝 C语言链表实现 | 青空之蓝 VSCode配置Java调试环境[Windows] | 青空之蓝 C 选择排序 | 青空之蓝 C 冒泡排序 | 青空之蓝 VSCode配置PHP调试环境[Windows] | 青空之蓝 VSCode配置C/C++ GDB调试环境[Windows] | 青空之蓝 WordPress友情链接模板 | 青空之蓝 Intel Optane 傲腾内存体验 | 青空之蓝 Mysql双机热备实战 | 青空之蓝 博客一年记录 | 青空之蓝 为WordPress启用Service Worker | 青空之蓝 Bing每日一图API | 青空之蓝 iframe延迟加载 | 青空之蓝 写在2018年高考前 | 青空之蓝 The Fox主题汉化分享 | 青空之蓝 [青空之蓝-2017]-崭新 | 青空之蓝 本博客评论规则 | 青空之蓝 世界,您好! | 青空之蓝
Java图实现 | 青空之蓝
Otstar Lin · 2019-05-05 · via 青空之蓝

没有介绍,请自行百度或谷歌,代码经过了一定的测试,但不保证没有 Bug。

package MyGraphDemo;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

/**
 * MyGraphDemo
 */
public class MyGraphDemo {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        MyGraph<Integer> gra = new MyGraph<Integer>();
        gra.add(null, 0, 1);
        gra.add(0, 1, 1);
        gra.add(0, 2, 1);
        gra.add(0, 3, 1);
        gra.add(1, 2, 1);
        gra.add(2, 3, 1);
        gra.testString();
        // List<MyGraph<Integer>.Vertex> list = gra.BFS(0, 3);
        // for (MyGraph<Integer>.Vertex var : list) {
        //     System.out.print(var.data);
        // }
        int[][] a = gra.toAssociationMatrix();
        for (int i = 0; i < 4; i++) {
            System.out.println(Arrays.toString(a[i]));
        }
        in.close();
    }
}

/**
 * MyGraph
 * Vertex中存放顶点的信息,以及连接点列表
 * Edge中存放权重,和与之连接点在VertexList中的索引
 */
class MyGraph<T extends Comparable> {
    List<Vertex> vertexList;
    List<EdgeNoPath> edgeList;
    MyGraph() {
        this.vertexList = new LinkedList<Vertex>();
        this.edgeList = new LinkedList<EdgeNoPath>();
    }
    // 顶点类
    class Vertex {
        T data;
        List<Edge> link;
        Vertex() {}
        Vertex(T data) {
            link = new LinkedList<Edge>();
            this.data = data;
        }
    }
    // 边类
    class Edge {
        int prev;
        int index;
        int weight;
        Edge(int index, int weight, int prev) {
            this.prev = prev;
            this.index = index;
            this.weight = weight;
        }
    }
    class EdgeNoPath {
        int[] index;
        int weight;
        EdgeNoPath(int index1, int index2, int weight) {
            boolean is = true;
            for (int i = 0; i < edgeList.size(); i++) {
                if((edgeList.get(i).index[0] == index1 && edgeList.get(i).index[1] == index2) || (edgeList.get(i).index[0] == index2 && edgeList.get(i).index[1] == index1)) {
                    is = false;
                    break;
                }
            }
            if(is) {
                this.weight = weight;
                this.index = new int[2];
                this.index[0] = index1;
                this.index[1] = index2;
            }
        }
    }
    /**
     * 添加顶点
     * @param prevData  连接的上一个顶点的数据
     * @param nextData  连接的上一个顶点的数据
     * @param weight    边的权重
     */
    public void add(T prevData, T nextData, int weight) {
        if(prevData == null && vertexList.size() == 0) {
            vertexList.add(new Vertex(nextData));
            return;
        } else if(prevData == null && vertexList.size() != 0) {
            return;
        }
        // 定位上一个节点
        int prev_index = this.getIndexFromData(prevData);
        int next_index = this.getIndexFromData(nextData);
        Vertex new_vertex;
        if(next_index == -1) {
            new_vertex = new Vertex(nextData);
            // 将新节点添加到顶点列表中
            vertexList.add(new_vertex);
            next_index = vertexList.size()-1;
        } else {
            new_vertex = vertexList.get(next_index);
        }
        // 将边的信息添加到新节点
        new_vertex.link.add(new Edge(prev_index, weight, next_index));
        // 将边的信息添加到上一个节点
        vertexList.get(prev_index).link.add(new Edge(next_index, weight, prev_index));
        edgeList.add(new EdgeNoPath(prev_index, next_index, weight));
    }
    /**
     * 获取制定data的顶点在顶点列表中的索引
     * @param data 要进行搜索的数据
     * @return     返回当前数据的顶点在顶点邻接表的索引,若未找到就返回 -1
     */
    public int getIndexFromData(T data) {
        int i = -1;
        while(vertexList.size() > i+1) {
            if(vertexList.get(i+1).data.compareTo(data) == 0) {
                i++;
                return i;
            }
            i++;
        }
        return -1;
    }
    // public int vertexOfEdge(T data) {

    // }
    public void testString() {
        for (Vertex var : vertexList) {
            System.out.print(var.data.toString() + ",");
            for (Edge v : var.link) {
                System.out.print(vertexList.get(v.index).data.toString()+" ");
            }
            System.out.println();
        }
    }
    // 深度优先搜索 - 递归隐藏方法
    private boolean DFS(Vertex vertex, T data, List<Vertex> list, boolean[] visited) {
        if(vertex == null) return false;
        if(vertex.data.compareTo(data) == 0) {
            list.add(vertex);
            return true;
        }
        for (int i = vertex.link.size()-1; i >= 0; i--) {
            int ver_index = vertex.link.get(i).index;
            if(!visited[ver_index]) {
                Vertex tempVertex = vertexList.get(ver_index);
                visited[ver_index] = true;
                boolean is = DFS(tempVertex, data, list, visited);
                if(is) {
                    list.add(vertex);
                    return true;
                }
                visited[ver_index] = false;
            }
        }
        return false;
    }
    /**
     * 深度优先搜索进行路径查找
     * @param startData 起点
     * @param Enddata   终点
     * @return          返回路径的点列表
     */
    public List<Vertex> DFS(T startData, T endData) {
        int start_index = this.getIndexFromData(startData);
        boolean[] visited = new boolean[vertexList.size()];
        visited[start_index] = true;
        List<Vertex> list = new ArrayList<Vertex>();
        DFS(vertexList.get(start_index), endData, list, visited);
        Collections.reverse(list);
        return list;
    }
    /**
     * 广度优先搜索进行路径查找
     * @param startData 起点
     * @param Enddata   终点
     * @return          返回路径的点列表
     */
    public List<Vertex> BFS(T startData, T endData) {
        int start_index = this.getIndexFromData(startData);
        BFS_Node endNode = null;
        List<BFS_Node> queue = new LinkedList<BFS_Node>();
        queue.add(new BFS_Node(vertexList.get(start_index), null));
        while (!queue.isEmpty()) {
            BFS_Node currentNode = queue.remove(0);
            if(currentNode.vertex.data.compareTo(endData) == 0) {
                endNode = currentNode;
                break;
            }
            for (int i = 0; i < currentNode.vertex.link.size(); i++) {
                queue.add(new BFS_Node(vertexList.get(currentNode.vertex.link.get(i).index), currentNode));
            }
        }
        List<Vertex> list = new LinkedList<Vertex>();
        while (endNode != null) {
            list.add(endNode.vertex);
            endNode = endNode.parent;
        }
        Collections.reverse(list);
        return list;
    }
    // 广度优先搜索进行路径追踪需要的类
    class BFS_Node {
        Vertex vertex;
        BFS_Node parent;
        BFS_Node(Vertex vertex, BFS_Node parent) {
            this.vertex = vertex;
            this.parent = parent;
        }
    }

    /**
     * 将顶点列表转换为顶点数组
     * @return 顶点数组
     */
    public Object[] toArraysVertex() {
        Object[] vertexs = vertexList.toArray();
        return vertexs;
    }
    /**
     * 将邻接表的图转换为邻接矩阵
     * @return 邻接矩阵数组
     */
    public int[][] toAdjacencyMatrix() {
        int vertexSize = vertexList.size();
        int[][] matrix = new int[vertexSize][vertexSize];
        for (int i = 0; i < vertexSize; i++) {
            Vertex currentVertex = vertexList.get(i);
            for (int j = 0; j < currentVertex.link.size(); j++) {
                Edge currentEdge = currentVertex.link.get(j);
                matrix[i][currentEdge.index] = currentEdge.weight;
            }
        }
        return matrix;
    }

    /**
     * 将邻接表图转换为关联矩阵
     * @return 关联矩阵数组
     */
    public int[][] toAssociationMatrix() {
        int vertexSize = vertexList.size();
        int edgeSize = edgeList.size();
        int[][] matrix = new int[vertexSize][edgeSize];
        for (int j = 0; j < edgeSize; j++) {
            EdgeNoPath currentEdge = edgeList.get(j);
            matrix[currentEdge.index[0]][j]++;
            matrix[currentEdge.index[1]][j]++;
        }
        return matrix;
    }
}
package MyGraphDemo;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

/**
 * MyGraphDemo
 */
public class MyGraphDemo {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        MyGraph<Integer> gra = new MyGraph<Integer>();
        gra.add(null, 0, 1);
        gra.add(0, 1, 1);
        gra.add(0, 2, 1);
        gra.add(0, 3, 1);
        gra.add(1, 2, 1);
        gra.add(2, 3, 1);
        gra.testString();
        // List<MyGraph<Integer>.Vertex> list = gra.BFS(0, 3);
        // for (MyGraph<Integer>.Vertex var : list) {
        //     System.out.print(var.data);
        // }
        int[][] a = gra.toAssociationMatrix();
        for (int i = 0; i < 4; i++) {
            System.out.println(Arrays.toString(a[i]));
        }
        in.close();
    }
}

/**
 * MyGraph
 * Vertex中存放顶点的信息,以及连接点列表
 * Edge中存放权重,和与之连接点在VertexList中的索引
 */
class MyGraph<T extends Comparable> {
    List<Vertex> vertexList;
    List<EdgeNoPath> edgeList;
    MyGraph() {
        this.vertexList = new LinkedList<Vertex>();
        this.edgeList = new LinkedList<EdgeNoPath>();
    }
    // 顶点类
    class Vertex {
        T data;
        List<Edge> link;
        Vertex() {}
        Vertex(T data) {
            link = new LinkedList<Edge>();
            this.data = data;
        }
    }
    // 边类
    class Edge {
        int prev;
        int index;
        int weight;
        Edge(int index, int weight, int prev) {
            this.prev = prev;
            this.index = index;
            this.weight = weight;
        }
    }
    class EdgeNoPath {
        int[] index;
        int weight;
        EdgeNoPath(int index1, int index2, int weight) {
            boolean is = true;
            for (int i = 0; i < edgeList.size(); i++) {
                if((edgeList.get(i).index[0] == index1 && edgeList.get(i).index[1] == index2) || (edgeList.get(i).index[0] == index2 && edgeList.get(i).index[1] == index1)) {
                    is = false;
                    break;
                }
            }
            if(is) {
                this.weight = weight;
                this.index = new int[2];
                this.index[0] = index1;
                this.index[1] = index2;
            }
        }
    }
    /**
     * 添加顶点
     * @param prevData  连接的上一个顶点的数据
     * @param nextData  连接的上一个顶点的数据
     * @param weight    边的权重
     */
    public void add(T prevData, T nextData, int weight) {
        if(prevData == null && vertexList.size() == 0) {
            vertexList.add(new Vertex(nextData));
            return;
        } else if(prevData == null && vertexList.size() != 0) {
            return;
        }
        // 定位上一个节点
        int prev_index = this.getIndexFromData(prevData);
        int next_index = this.getIndexFromData(nextData);
        Vertex new_vertex;
        if(next_index == -1) {
            new_vertex = new Vertex(nextData);
            // 将新节点添加到顶点列表中
            vertexList.add(new_vertex);
            next_index = vertexList.size()-1;
        } else {
            new_vertex = vertexList.get(next_index);
        }
        // 将边的信息添加到新节点
        new_vertex.link.add(new Edge(prev_index, weight, next_index));
        // 将边的信息添加到上一个节点
        vertexList.get(prev_index).link.add(new Edge(next_index, weight, prev_index));
        edgeList.add(new EdgeNoPath(prev_index, next_index, weight));
    }
    /**
     * 获取制定data的顶点在顶点列表中的索引
     * @param data 要进行搜索的数据
     * @return     返回当前数据的顶点在顶点邻接表的索引,若未找到就返回 -1
     */
    public int getIndexFromData(T data) {
        int i = -1;
        while(vertexList.size() > i+1) {
            if(vertexList.get(i+1).data.compareTo(data) == 0) {
                i++;
                return i;
            }
            i++;
        }
        return -1;
    }
    // public int vertexOfEdge(T data) {

    // }
    public void testString() {
        for (Vertex var : vertexList) {
            System.out.print(var.data.toString() + ",");
            for (Edge v : var.link) {
                System.out.print(vertexList.get(v.index).data.toString()+" ");
            }
            System.out.println();
        }
    }
    // 深度优先搜索 - 递归隐藏方法
    private boolean DFS(Vertex vertex, T data, List<Vertex> list, boolean[] visited) {
        if(vertex == null) return false;
        if(vertex.data.compareTo(data) == 0) {
            list.add(vertex);
            return true;
        }
        for (int i = vertex.link.size()-1; i >= 0; i--) {
            int ver_index = vertex.link.get(i).index;
            if(!visited[ver_index]) {
                Vertex tempVertex = vertexList.get(ver_index);
                visited[ver_index] = true;
                boolean is = DFS(tempVertex, data, list, visited);
                if(is) {
                    list.add(vertex);
                    return true;
                }
                visited[ver_index] = false;
            }
        }
        return false;
    }
    /**
     * 深度优先搜索进行路径查找
     * @param startData 起点
     * @param Enddata   终点
     * @return          返回路径的点列表
     */
    public List<Vertex> DFS(T startData, T endData) {
        int start_index = this.getIndexFromData(startData);
        boolean[] visited = new boolean[vertexList.size()];
        visited[start_index] = true;
        List<Vertex> list = new ArrayList<Vertex>();
        DFS(vertexList.get(start_index), endData, list, visited);
        Collections.reverse(list);
        return list;
    }
    /**
     * 广度优先搜索进行路径查找
     * @param startData 起点
     * @param Enddata   终点
     * @return          返回路径的点列表
     */
    public List<Vertex> BFS(T startData, T endData) {
        int start_index = this.getIndexFromData(startData);
        BFS_Node endNode = null;
        List<BFS_Node> queue = new LinkedList<BFS_Node>();
        queue.add(new BFS_Node(vertexList.get(start_index), null));
        while (!queue.isEmpty()) {
            BFS_Node currentNode = queue.remove(0);
            if(currentNode.vertex.data.compareTo(endData) == 0) {
                endNode = currentNode;
                break;
            }
            for (int i = 0; i < currentNode.vertex.link.size(); i++) {
                queue.add(new BFS_Node(vertexList.get(currentNode.vertex.link.get(i).index), currentNode));
            }
        }
        List<Vertex> list = new LinkedList<Vertex>();
        while (endNode != null) {
            list.add(endNode.vertex);
            endNode = endNode.parent;
        }
        Collections.reverse(list);
        return list;
    }
    // 广度优先搜索进行路径追踪需要的类
    class BFS_Node {
        Vertex vertex;
        BFS_Node parent;
        BFS_Node(Vertex vertex, BFS_Node parent) {
            this.vertex = vertex;
            this.parent = parent;
        }
    }

    /**
     * 将顶点列表转换为顶点数组
     * @return 顶点数组
     */
    public Object[] toArraysVertex() {
        Object[] vertexs = vertexList.toArray();
        return vertexs;
    }
    /**
     * 将邻接表的图转换为邻接矩阵
     * @return 邻接矩阵数组
     */
    public int[][] toAdjacencyMatrix() {
        int vertexSize = vertexList.size();
        int[][] matrix = new int[vertexSize][vertexSize];
        for (int i = 0; i < vertexSize; i++) {
            Vertex currentVertex = vertexList.get(i);
            for (int j = 0; j < currentVertex.link.size(); j++) {
                Edge currentEdge = currentVertex.link.get(j);
                matrix[i][currentEdge.index] = currentEdge.weight;
            }
        }
        return matrix;
    }

    /**
     * 将邻接表图转换为关联矩阵
     * @return 关联矩阵数组
     */
    public int[][] toAssociationMatrix() {
        int vertexSize = vertexList.size();
        int edgeSize = edgeList.size();
        int[][] matrix = new int[vertexSize][edgeSize];
        for (int j = 0; j < edgeSize; j++) {
            EdgeNoPath currentEdge = edgeList.get(j);
            matrix[currentEdge.index[0]][j]++;
            matrix[currentEdge.index[1]][j]++;
        }
        return matrix;
    }
}

Java图实现

https://blog.ixk.me/post/java-graph-implementation
  • 许可协议

    BY-NC-SA

  • 本文作者

    Otstar Lin

  • 发布于

    2019/05/05

转载或引用本文时请遵守许可协议,注明出处、不得用于商业用途!

Java二叉树实现为apt方式安装的nginx重新编译增加WebDAV