图的结构
/**
* 图结构
*/
export default class Graph{
public nodes:Map<number,GNode>; //点集(点的权值为key,点为value)
public edges:Edge[]; //边集
constructor(){
this.nodes = new Map<number,GNode>();
this.edges = [];
}
}
/**
* 点
*/
export class GNode{
public value:number;
public in:number; //入度(有多少边指向自己)
public out:number; //出度 (有多少边从自己指出去)
public nexts:GNode[]; //由自己指出去的边连到的点
public edges:Edge[]; //由自己指出去的边
constructor(value:number){
this.value = value;
this.in = 0;
this.out = 0;
this.nexts = [];
this.edges = [];
}
}
/**
* 边
*/
export class Edge{
public weight:number; //权值(距离)
public from:GNode;
public to:GNode;
constructor(weight:number,from:GNode,to:GNode){
this.weight = weight;
this.from = from;
this.to = to;
}
}
以上结构为个人偏好写法,做题时可以将其他的形式的图转换为自己熟悉的结构。
创建图
/**
* @param matrix 所有的边
* [[weight权值,from节点上的值,to节点上的值]...]
*/
createGraph(matrix: number[][]) {
let graph = new Graph();
for (let i = 0; i < matrix.length; i++) {
let weight = matrix[i][0];
let from = matrix[i][1];
let to = matrix[i][2];
if (!graph.nodes.get(from)) {
graph.nodes.set(from, new GNode(from));
}
if (!graph.nodes.get(to)) {
graph.nodes.set(to, new GNode(from));
}
let fromN = graph.nodes.get(from);
let toN = graph.nodes.get(to)
fromN.out++;
toN.in++;
fromN.nexts.push(toN);
let edge = new Edge(weight, graph.nodes.get(from), graph.nodes.get(to));
graph.edges.push(edge);
fromN.edges.push(edge);
}
return graph;
}
图的宽度优先遍历
/**
* 图的宽度优先遍历
* 利用队列实现
* 源节点入栈
* 1、弹出一个节点,打印
* 2、把该节点中所没有进过队列的邻接点放入队列
* 循环1、2直到队列变空
*/
graphBfs(node: GNode) {
if (node == null) return;
let quene = [];
quene.unshift(node);
let list = []; //记录已经入过队列的节点
list.push(node);
while (quene.length != 0) {
let cur = quene.pop();
console.log("宽度遍历图节点", cur.value);
for (let next of cur.nexts) {
if (list.indexOf(next) == -1) {
quene.unshift(next);
list.push(next);
}
}
}
}
图的深度优先遍历
/**
* 图的深度优先遍历
* 利用栈实现
* 源节点入栈,打印
* 1、从栈中弹出一个点
* 2、把该节点中所没有进过栈的一个邻接点next放入栈中,并在此之前先将自己放回栈中。打印next。
* 循环1、2直到栈变空
*/
graphDfs(node: GNode) {
if (node == null) return;
let stack = [];
stack.push(node);
let list = []; //记录已经入过队列的节点
list.push(node);
console.log("深度遍历图节点", node.value);
while (stack.length != 0) {
let cur = stack.pop();
for (let next of cur.nexts) {
if (list.indexOf(next) == -1) {
stack.unshift(cur);
stack.unshift(next);
list.push(next);
console.log("深度遍历图节点", next.value);
break;
}
}
}
}