zoukankan      html  css  js  c++  java
  • 图论_图结构的基础理论知识

    图结构

                1. 图也是一种常见的数据结构

                2. 图是一种和树结构由些相似的数据结构

                3. 图结构也图论,在数学的概念上,树是图的一种

                4. 图论以图为研究对象,研究顶点和边组成的图形的数学理论和方法

    图结构的使用场景

                1. 人与人之间的关系网(六度空间理论)

                2. 地铁路线图

                3. 村庄间的路线图

    图结构的特点

                1. 图结构中有两个重要的概念:顶点和边

                2. 一组顶点:通常用V(Vertex)表示顶点的集合

                3. 一组边:通常边用E(Edge)表示边的集合

                        边表示顶点与顶点之间的连线

                        边可以是有向的也可以是无向的

                        如:A -- B表示无向, A --> B表示有向

    图结构的常见术语

                1. 顶点

                2. 边

                3. 相邻顶点:通过一条边可以连接起来的两个顶点互为相邻顶点

                4. 顶点的度:一个顶点所连的相邻顶点的个数叫做顶点的度

                5. 路径:由顶点V1, V2, ...组成的一个连续的序列叫做一条路径

                    简单路径:不包含重复的顶点

                    贿赂:第一个顶点和最后一个顶点相同的路径成为回路

                6. 有向图:边为有向的图

                7. 无向图:边全为无向的图

                8. 带权图:边携带一个权重的图

                9. 无权图:边没有权重的图

    图的信息:

                一个图结构需要包含以下信息:

                    1. 顶点的表示:

                        抽象成1 2 3... 或者A B C D...

                    2. 边的表示:

                        邻接矩阵,即一个二维数组表示相邻顶点直接按的距离

                        邻接矩阵可以方便的表示有向图和无向图,带权图和无权图。

                        邻接矩阵的问题:

                            邻接矩阵中,如果用0表示无边,1表示有边,当顶点较多,边较少时,邻接矩阵就是一个稀疏矩阵,造成存储空间的浪费

                        邻接表:邻接表也是一种表示边的存储方式,作用和邻接矩阵一样

                            1. 邻接表由每个顶顶以及和顶点相邻的顶点列表组成

                        邻接表存在的问题:

                            1. 出度容易计算,入度计算比较麻烦

                                出度:一个顶点连接的相邻顶点

                                入度:连接顶点的相邻顶点

    图结构的封装:

                1. 数据存储:

                    1. 顶点用数组存储

                    2. 边用邻接表存储

                2. 属性

                    1. this.vertexs     顶点(数组)

                    2. this.edges       字典

                3. 方法

                    1. addVertex()      添加顶点

                    2. addEdge()        添加边

                    3. toString()       返回邻接表

                    4. 顶点遍历

                        1. 广度优先搜索(Breadth-First Search, BFS)

                            基于队列,入队列的顶点先被访问,顺序和层序遍历一样

                        2. 深度优先搜索(Depth-First Search, DFS)

                            基于栈或递归,

                        这两种遍历算法都需要指定第一个被访问的顶点

    图结构的代码实现:

    function Graph(){
            // 图的属性
            // 1. 图的顶点(数组)
            // 2. 图的边(字典)
            this.vertexs = [];
            this.edges = {};
    
            // 图的方法
            // 1. 添加顶点  addVertex()
            Graph.prototype.addVertex = function(v){
                this.vertexs.push(v);
                this.edges[v] = [];
            }
    
            // 2. 添加边    addEdge()
            Graph.prototype.addEdge = function(v1, v2){
                if(this.edges[v1].indexOf(v2) == -1){
                    this.edges[v1].push(v2);
                }
                if(this.edges[v2].indexOf(v1) == -1){
                    this.edges[v2].push(v1);
                }
            }
    
            // 3. 打印邻接表    toString()
            Graph.prototype.toString = function(){
                var res = "";
                for(var i = 0; i < this.vertexs.length; i++){
                    res = res + this.vertexs[i] + " |-->| ";
                    // 这里的item为取出的邻接表中的一项(即一个数组)
                    var item = this.edges[this.vertexs[i]];
                    for(var j = 0; j < item.length; j++){
                        res = res + item[j] + " ";
                    }
                    res = res + "
    ";
                }
                return res;
            }
    
            // 4. 颜色初始化
            Graph.prototype.initColor = function(){
                var colors = {};
                for(var k = 0; k < this.vertexs.length; k++){
                    colors[this.vertexs[k]] = 'white';
                }
                return colors;
            }
    
            // 5. 图的遍历
            /*
                广度优先搜索(Breadth-First Search, BFS)
                    基于队列,入队列的顶点先被
                深度优先搜索(Depth-First Search, DFS)
                    基于栈或递归,
                这两种遍历算法都需要指定第一个被访问的顶点
            */
            // 5.1 广度优先搜索
            Graph.prototype.bfs = function(firstV){
                // 1. 初始化颜色
                var colors = this.initColor();
    
                // 2. 创建队列
                var q = new Queue();
    
                // 3. 将初始顶点压入队列
                q.enqueue(firstV);
                colors[firstV] = 'gray';
    
                var resultString = "";
                // 4. 循环遍历,将所有的顶点都压入队列
                while(!q.isEmpty()){
                    // 4.1 取出队列头部的顶点
                    var v = q.dequeue();
                    // console.log(v);
                    resultString += v + " ";
    
                    // 4.2 获取这个顶点的相邻顶点
                    var vList = this.edges[v];
    
                    // 4.3 将这些顶点压入队列中
                    for(var j = 0; j < vList.length; j++){
                        if(colors[vList[j]] == 'white'){
                            // 颜色为white表示未被访问过
                            q.enqueue(vList[j]);
    
                            // 将颜色设置为gray表示已经压入队列了
                            colors[vList[j]] = 'gray';
                        }
                    }
                }
    
                // 5. 返回字符串
                return resultString;
            }
    
            // 5.2 深度优先搜索
            Graph.prototype.dfs = function(firstV, colors){
                var colors = this.initColor();
                var res = "";
                this.dfsV(firstV, colors, function(vertex){
                    res += vertex + " ";
                });
                return res;
            }
            Graph.prototype.dfsV = function(v, colors, handler){
                // 1. 处理这个节点
                handler(v);
                colors[v] = 'red';
    
                // 2. 取出邻接表一个元素数组
                var vlist = this.edges[v];
    
                // 3. 依次访问取出的数组中的元素
                for(var k = 0; k < vlist.length; k ++){
                    if(colors[vlist[k]] == 'white'){
                        this.dfsV(vlist[k], colors, handler);
                    }
                }
                
            }
        }
    View Code

                 

  • 相关阅读:
    挖矿病毒入侵-分析总结
    Linux查看包依赖关系的神器-repoquery分享
    Elasticsearch 字段为空(null)记录查询
    Python 导数 Elasticsearch 元数据到CSV
    基于docker快速构建MySQL主从复制环境
    Redis环境简单部署(集群/双机)
    FTP 脚本 to Shell脚本&bat脚本&python脚本
    专用服务器模式&共享服务器模式
    CentOS 7安装部署ELK 6.2.4-SUCCESS
    zabbix 数据库迁移变更
  • 原文地址:https://www.cnblogs.com/carreyBlog/p/13657160.html
Copyright © 2011-2022 走看看