TS写图的遍历

图的结构

/**
 * 图结构 
 */
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;
                }
            }
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值