JavaScript实现数据结构与算法(五)图结构

  • (五)图论
  • 1. 图的相关概念
  • 1.1 什么是图
  • 1.2 图的现实案例
  • 1.3 图结构的特点
  • 1.4 图的术语
  • 1.4.1 顶点
  • 1.4.2 度
  • 1.4.3 路径
  • 1.4.4 简单路径
  • 1.4.5 回路
  • 1.4.6 无向图
  • 1.4.7 有向图
  • 1.4.8 无权图
  • 1.4.9 带权图
  • 2. 图的表示
  • 2.1 邻接矩阵
  • 2.1.1 邻接矩阵的表示方法
  • 2.1.2 邻接矩阵的缺点
  • 2.2 邻接表
  • 2.2.1 表示方法
  • 2.2.2 解析
  • 2.2.3 问题
  • 2.2.4 添加边
  • 2.2.5 代码实现
  • 2.3 关联矩阵
  • 3. 自定义图
  • 4. 图的遍历
  • 4.1 广度优先搜素(BFS)
  • 4.1.1 思路
  • 4.1.2 思想与实现方法
  • 4.2 深度优先搜素(DFS)
  • 4.2.1 思路
  • 4.2.2 思想与实现方法
  • 4.3 实现代码


(五)图论

1. 图的相关概念

1.1 什么是图

js数据结构与算法第三版下载 javascript数据结构与算法百度云_数据结构

1.2 图的现实案例
1.3 图结构的特点

js数据结构与算法第三版下载 javascript数据结构与算法百度云_算法_02

1.4 图的术语
1.4.1 顶点

js数据结构与算法第三版下载 javascript数据结构与算法百度云_图论_03

1.4.2 度

js数据结构与算法第三版下载 javascript数据结构与算法百度云_数据结构_04

1.4.3 路径

js数据结构与算法第三版下载 javascript数据结构与算法百度云_算法_05

1.4.4 简单路径

js数据结构与算法第三版下载 javascript数据结构与算法百度云_javascript_06

1.4.5 回路

js数据结构与算法第三版下载 javascript数据结构与算法百度云_图论_07

1.4.6 无向图

js数据结构与算法第三版下载 javascript数据结构与算法百度云_数据结构_08

1.4.7 有向图

js数据结构与算法第三版下载 javascript数据结构与算法百度云_js数据结构与算法第三版下载_09

1.4.8 无权图

js数据结构与算法第三版下载 javascript数据结构与算法百度云_算法_10


js数据结构与算法第三版下载 javascript数据结构与算法百度云_数据结构_11

1.4.9 带权图

js数据结构与算法第三版下载 javascript数据结构与算法百度云_图论_12


js数据结构与算法第三版下载 javascript数据结构与算法百度云_javascript_13

2. 图的表示

2.1 邻接矩阵
2.1.1 邻接矩阵的表示方法

js数据结构与算法第三版下载 javascript数据结构与算法百度云_数据结构_14


js数据结构与算法第三版下载 javascript数据结构与算法百度云_js数据结构与算法第三版下载_15


js数据结构与算法第三版下载 javascript数据结构与算法百度云_javascript_16

2.1.2 邻接矩阵的缺点

js数据结构与算法第三版下载 javascript数据结构与算法百度云_javascript_17

2.2 邻接表
2.2.1 表示方法

js数据结构与算法第三版下载 javascript数据结构与算法百度云_算法_18

2.2.2 解析

js数据结构与算法第三版下载 javascript数据结构与算法百度云_算法_19


js数据结构与算法第三版下载 javascript数据结构与算法百度云_js数据结构与算法第三版下载_20

2.2.3 问题

js数据结构与算法第三版下载 javascript数据结构与算法百度云_图论_21

2.2.4 添加边

js数据结构与算法第三版下载 javascript数据结构与算法百度云_javascript_22

2.2.5 代码实现

(1)代码部分

// 封装图结构
    function Graph() {
        // 属性:定点(数组)/边(字典)
        this.vertexes = []; // 定点
        this.edges = new Dictionary();  // 边

        // 方法
        // 添加方法
        // 1. 添加顶点的方法
        Graph.prototype.addVertex = function (v) {
            this.vertexes.push(v);
            this.edges.set(v,[]);
        };

        // 2. 添加边的方法
        Graph.prototype.addEdge = function (v1,v2) {
            this.edges.get(v1).push(v2);
            this.edges.get(v2).push(v1);
        };

        // 3. 实现toString方法
        Graph.prototype.toString = function () {
            // 1. 定义字符串,保存最终的结果
            var resultString = "";

            // 2. 遍历所有的顶点,以及顶点对应的边
            for (var i = 0 ; i < this.vertexes.length; i++){

                resultString += this.vertexes[i] + "->";
                var vEdges = this.edges.get(this.vertexes[i]);
                for (var j = 0; j < vEdges.length; j++){
                    resultString += vEdges[j] + " ";
                };
                resultString += "\n";
            };
            return resultString;
        }


    };

(2)测试代码

// 测试代码
    // 1. 创建图结构
    var g =new Graph();

    // 2. 添加顶点
    var myVertexes = ['A','B','C','D','E','F','G','H','I'];
    for (var i = 0; i < myVertexes.length ; i++){
        g.addVertex(myVertexes[i]);
    };

    // 3.添加边
    g.addEdge('A','B');
    g.addEdge('A','C');
    g.addEdge('A','D');
    g.addEdge('C','D');
    g.addEdge('C','G');
    g.addEdge('D','G');
    g.addEdge('D','H');
    g.addEdge('B','E');
    g.addEdge('B','F');
    g.addEdge('E','I');
    alert('aaa');
    // 4. 测试结果
    alert(g);

(3)运行结果

js数据结构与算法第三版下载 javascript数据结构与算法百度云_javascript_23

2.3 关联矩阵

3. 自定义图

4. 图的遍历

思想:

js数据结构与算法第三版下载 javascript数据结构与算法百度云_算法_24

4.1 广度优先搜素(BFS)

需要明确指定第一个被访问的顶点

js数据结构与算法第三版下载 javascript数据结构与算法百度云_js数据结构与算法第三版下载_25

4.1.1 思路

js数据结构与算法第三版下载 javascript数据结构与算法百度云_算法_26

4.1.2 思想与实现方法

js数据结构与算法第三版下载 javascript数据结构与算法百度云_图论_27

4.2 深度优先搜素(DFS)

需要明确指定第一个被访问的顶点

js数据结构与算法第三版下载 javascript数据结构与算法百度云_数据结构_28


js数据结构与算法第三版下载 javascript数据结构与算法百度云_数据结构_29

4.2.1 思路

js数据结构与算法第三版下载 javascript数据结构与算法百度云_数据结构_30

4.2.2 思想与实现方法

js数据结构与算法第三版下载 javascript数据结构与算法百度云_数据结构_31

4.3 实现代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>图结构</title>
</head>
<body>
<script src="dict.js"></script>
<script src="queue.js"></script>
<script>
    // 封装图结构
    function Graph() {
        // 属性:定点(数组)/边(字典)
        this.vertexes = []; // 定点
        this.edges = new Dictionary();  // 边

        // 方法
        // 添加方法
        // 1. 添加顶点的方法
        Graph.prototype.addVertex = function (v) {
            this.vertexes.push(v);
            this.edges.set(v,[]);
        };

        // 2. 添加边的方法
        Graph.prototype.addEdge = function (v1,v2) {
            this.edges.get(v1).push(v2);
            this.edges.get(v2).push(v1);
        };

        // 3. 实现toString方法
        Graph.prototype.toString = function () {
            // 1. 定义字符串,保存最终的结果
            var resultString = "";

            // 2. 遍历所有的顶点,以及顶点对应的边
            for (var i = 0 ; i < this.vertexes.length; i++){

                resultString += this.vertexes[i] + "->";
                var vEdges = this.edges.get(this.vertexes[i]);
                for (var j = 0; j < vEdges.length; j++){
                    resultString += vEdges[j] + " ";
                };
                resultString += "\n";
            };
            return resultString;
        };

        // 初始化状态颜色
        Graph.prototype.initializeColor = function () {
          var colors = [];
          for (var i = 0 ;i < this.vertexes.length; i++){
              colors[this.vertexes[i]] = "white";
          }
          return colors;
        };

        // 实现广度优先搜索(BFS)
        Graph.prototype.bfs = function (initV,handler) {
            // 1. 初始化颜色
            var colors = this.initializeColor();

            // 2. 创建队列
            var queue = new Queue();

            // 3. 将顶点加入到队列中
            queue.enqueue(initV);

            // 4. 循环从队列中取出元素
            while(!queue.isEmpty()){
                // 4.1 从队列中取出一个顶点
                var v = queue.dequeue();

                // 4.2 获取和顶点相连的其他顶点
                var vList = this.edges.get(v);

                // 4.3 将v的颜色设置成灰色
                colors[v] = 'gray';

                // 4.4 遍历所有的顶点,并且加入到队列中
                for (var i = 0; i < vList.length; i++){
                    var e = vList[i];
                    if(colors[e] == 'white'){
                        colors[e] = 'gray';
                        queue.enqueue(e);
                    }
                };

                // 4.5 v已经被探测,并且访问顶点
                handler(v);

                // 4.6 将顶点设置为黑色
                colors[v] = 'black';


            }
        };
        
        // 实现深度优先搜索(DFS)
        Graph.prototype.dfs = function (initV,handler) {
            // 1. 初始化颜色
            var colors = this.initializeColor();

            // 2. 创建队列
            var queue = new Queue();

            // 3. 将顶点加入到队列中
            queue.enqueue(initV);

            // 4. 循环从队列中取出元素
            while(!queue.isEmpty()){
                // 4.1 从队列中取出一个顶点
                var v = queue.dequeue();

                // 4.2 从某个顶点开始依次递归访问
                this.dfsVisit(v,colors,handler);

            }
        };

        Graph.prototype.dfsVisit = function (v,colors,handler) {
            // 1. 将颜色设置为灰色
            colors[v] = "gray";

            // 2. 处理v顶点
            handler(v);

            // 3. 访问v相连的顶点
            var vList = this.edges.get(v);
            for (var i = 0 ; i < vList.length ; i++){
                var e = vList[i];
                if (colors[e] == "white"){
                    this.dfsVisit(e,colors,handler);
                }
            }

            // 4. 将v设置为黑色
            colors[v] = "black";


        };


    };
    // 测试代码
    // 1. 创建图结构
    var g =new Graph();

    // 2. 添加顶点
    var myVertexes = ['A','B','C','D','E','F','G','H','I'];
    for (var i = 0; i < myVertexes.length ; i++){
        g.addVertex(myVertexes[i]);
    };

    // 3.添加边
    g.addEdge('A','B');
    g.addEdge('A','C');
    g.addEdge('A','D');
    g.addEdge('C','D');
    g.addEdge('C','G');
    g.addEdge('D','G');
    g.addEdge('D','H');
    g.addEdge('B','E');
    g.addEdge('B','F');
    g.addEdge('E','I');

    // 4. 测试结果
    // alert(g);


    // 5. 测试bfs
    var result = "";
    g.bfs(g.vertexes[0],function (v) {
        result += v + ' ';
    });
    // alert(result);

    // 6. 测试dfs
    result = "";
    g.dfs(g.vertexes[0],function (v) {
        result += v + ' ';
    });
    alert(result);


</script>
</body>
</html>