• 数据结构图(非带权图)(js)


    好久没js

    1.顶点

    //定义顶点
    var Vertex = function (label) {
        this._label = label;
        this._wasVisited = false;
    }
    

    2.图

    //定义图
    var Graph = function () {
        var max_vertx = 20;
        this.vertexList = new Array(max_vertx);
        this.adjMat = [];
        this.length = 0;
        for (var i = 0; i < max_vertx; i++) {
            this.adjMat.push([]);
            for (var j = 0; j < max_vertx; j++) {
                this.adjMat[i][j] = 0;
            }
        }
    };
    

    3.添加顶点和边

    //添加顶点
    Graph.prototype.AddVertex = function (label) {
        var vertex = new Vertex(label);
        this.vertexList.push(vertex);
        this.length++;
    };
    //添加边
    Graph.prototype.AddEdge = function (start, end) {
        adjMat[start][end] = 1;
        adjMat[end][start] = 1;
    }
    


    4.深度优先遍历

    规则:
    1.访问一个领接点未访问的顶点并标记为访问,然后放入栈中
    2.如果1无法执行且栈不为空,则弹出一个顶点然后继续执行1
    3.无法1,2均无法执行则结束遍历

    so先定义一个栈

    Stack

    var Stack = function () {
        this._array = new Array(10);
        this.top = -1;
    }
    Stack.prototype.Push = function (obj) {
        this._array[++this.top] = obj;
    };
    Stack.prototype.Peek = function () {
        return this._array[this.top];
    };
    Stack.prototype.Pop = function () {
        return this._array[this.top--];
    };
    Stack.prototype.IsEmpty = function () {
        return this.top == -1;
    };
    

    (1)把第一个放入栈
    if (this.length == 0) return;
    this.vertexList[0].wasVisited = true;
    this.vertexList[0].Display();
    this.vertStack.Push(0);
    
    (2)取邻接点
    var length = this.length;
    var adjMat = this.adjMat;
    var vertexList = this.vertexList;
    var unvisitedVertex = function (v) {
        for (var i = 0; i < length; i++) {
            if (adjMat[v][i] == 1 && !vertexList[i].wasVisited)
                return i;
        }
        return -1;
    }
    
    (3)在栈不为空的情况下,并进行标记遍历
    while (!this.vertStack.IsEmpty()) {
        var v = unvisitedVertex(this.vertStack.Peek());
        if (v == -1)
            this.vertStack.Pop();
        else {
            this.vertexList[v].wasVisited = true;
            this.vertexList[v].Display();
            this.vertStack.Push(v);
        }
    }
    
    Test
    var entity = new Graph();
    //添加顶点
    entity.AddVertex("A");
    entity.AddVertex("B");
    entity.AddVertex("C");
    entity.AddVertex("D");
    entity.AddVertex("E");
    //添加边
    entity.AddEdge(0, 1);//AB
    entity.AddEdge(1, 2); //BC
    entity.AddEdge(0, 3); //AD
    entity.AddEdge(3, 4); //DE
     entity.dfs();
    


    5.广度优先遍历
    规则:

    1.访问当前点的所有邻接点,标记它,并放入队列中
    2.如果邻接点访问完毕后,则从队列中取一个邻接点重复1步骤
    3.当1和2完毕后则完成
    先定义一个Queue

    var Queue = function () {
        this.Max_Size = 10;
        this._array = new Array(this.Max_Size);
        this.head = 0;
        this.rear = -1;
    }
    Queue.prototype.Enqueue = function (obj) {
        this._array[++this.rear] = obj;
    };
    Queue.prototype.Dequeue = function () {
        return this._array[this.head++];
    };
    Queue.prototype.IsEmpty = function () {
        return (this.rear + 1 == this.head || (this.head + this.Max_Size - 1 == this.rear));
    };
    

    bfs
    1.标记第一个点

    this.vertexList[0].wasVisited = true;
    this.vertexList[0].Display();
    this.vertQueue.Enqueue(0);
    

    2.当有邻接点则显示,否则则从队列中取

    while (!this.vertQueue.IsEmpty()) {
        var v1 = this.vertQueue.Dequeue();
        var v2;
        while ((v2=unvisitedVertex(v1))!=-1) {
            this.vertexList[v2].wasVisited = true;
            this.vertexList[v2].Display();
            this.vertQueue.Enqueue(v2);
        }
    }
    
    完整
    Graph.prototype.bfs = function () {
        if (this.length == 0) return;
        this.vertexList[0].wasVisited = true;
        this.vertexList[0].Display();
        this.vertQueue.Enqueue(0);
    
        var length = this.length;
        var adjMat = this.adjMat;
        var vertexList = this.vertexList;
        var unvisitedVertex = function (v) {
            for (var i = 0; i < length; i++) {
                if (adjMat[v][i] == 1 && !vertexList[i].wasVisited)
                    return i;
            }
            return -1;
        }
        while (!this.vertQueue.IsEmpty()) {
            var v1 = this.vertQueue.Dequeue();
            var v2;
            while ((v2=unvisitedVertex(v1))!=-1) {
                this.vertexList[v2].wasVisited = true;
                this.vertexList[v2].Display();
                this.vertQueue.Enqueue(v2);
            }
        }
    }
    


    6.最小生成树
    一个图的最小生成树可能有很多种,
    采用深度遍历.不同之处在于将当前值给记录下来,
    与4比较

    Graph.prototype.mst = function () {
        if (this.length == 0) return;
        this.vertexList[0].wasVisited = true;
        this.vertStack.Push(0);
    
        var length = this.length;
        var adjMat = this.adjMat;
        var vertexList = this.vertexList;
        var unvisitedVertex = function (v) {
            for (var i = 0; i < length; i++) {
                if (adjMat[v][i] == 1 && !vertexList[i].wasVisited)
                    return i;
            }
            return -1;
        }
        while (!this.vertStack.IsEmpty()) {
            var currentVertex = this.vertStack.Peek();
            var v = unvisitedVertex(currentVertex);
            if (v == -1)
                this.vertStack.Pop();
            else {
                this.vertexList[v].wasVisited = true;
                this.vertexList[currentVertex].Display();
                this.vertexList[v].Display();
                this.vertStack.Push(v);
            }
        }
    }
    

    7.拓扑排序

    在有向图的情况下,如课程选择,有先后顺序原则.
    规则:
    1.找到一个没有后继的顶点,删除这个顶点并做标记,并重复,直到删除完为止
    (1)有向图只需要添加一边

    Graph.prototype.AddSingleEdge = function (start, end) {
        this.adjMat[start][end] = 1;
    };
    

    (2)delete

          Graph.prototype.DeleteVertex = function (index) {
              var nVerts = this.length;
              if (index != this.length - 1) {
                  //move
                  for (var i = index; i < nVerts - 1; i++) {
                      this.vertexList[i] = this.vertexList[i + 1];
                  }
                  //delete arrry from table
                  //move up
                  for (var i = index; i < nVerts - 1; i++) {
                      this.moveRowUp(i, nVerts);
                  }
                  //move left
                  for (var i = index; i < nVerts - 1; i++) {
                      this.moveColLeft(i, nVerts-1);
                  }
              }
              this.length--;
          };
    Graph.prototype.moveRowUp=function(row, length)
    {
    for(var col=0; col<length; col++)
       this.adjMat[row][col] = this.adjMat[row+1][col];
    }
    Graph.prototype.moveColLeft = function (col, length) {
        for (var row = 0; row < length; row++)
            this.adjMat[row][col] = this.adjMat[row][col + 1];
    }
    

    (3)topo

    Graph.prototype.Topo = function () {
        
        while (this.length > 0) {
            var currentVertex = this.noSuccessors();
            if (currentVertex == -1)
                return;
            this.sortArray[this.length-1]=this.vertexList[currentVertex]._label;
            this.DeleteVertex(currentVertex);
        }
    };
    Graph.prototype.noSuccessors = function () {
        var isEdge = false;
        for (var i = 0; i < this.length; i++) {
            isEdge = false;
            for (var j = 0; j < this.length; j++) {
                if (this.adjMat[i][j] > 0) {
                    isEdge = true;
                    break;
                }
            }
            if (!isEdge)
                return i;
        }
        return -1;
    };
    


    8.Warshall算法

  • 相关阅读:
    CF #536div2E(dp)
    BZOJ2440(容斥+莫比乌斯函数)
    莫比乌斯反演题目结(下)
    struts 文件上传示例
    struts 文件上传示例
    struts2请求过程源码分析
    struts2请求过程源码分析
    如何快速成为数据分析师?
    如何快速成为数据分析师?
    多对多 hibernate映射
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/1800017.html
Copyright © 2020-2023  润新知