深度优先算法

深度优先算法

深度优先百度百科

深度优先遍历图的方法是,从图中某顶点v出发:
(1)访问顶点v;
(2)依次从v的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v有路径相通的顶点都被访问;
(3)若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止。

有点不太好理解

二维数组数据结构就如图所示 整个节点构成的图 是一个二维数组,当进行深度优先的时候先以黑色箭头为指向的下标节点开始搜索,先搜索 arr[0][index] 开始找到存在通路的第一个节点且该节点没有被访问过,找到后就将黑色箭头移到对应的index 即 black_index = index, 然后继续搜索,找到第一个通路的节点,当节点被访问过就继续查找arr[black_index][index]的下一个节点是否是通路,如果找到了继续移动黑色箭头。

简单的说 直接搜索对应的black_index 对应的一维数组中依次查找能够联通的节点,找到了就从红色箭头代表的index 赋值给 black_index 然后再再这个black_index中查找,并标记已经查找过的节点,如果第一次还没搜索完成,那么就将black_index 加 1 后再查找。

namespace DataStructure {

    export class MapGrap {

        private edges: number[][]; // 边对应的数据
        private vertexs: string[]; // 顶点数据
        private numberOfEdges: number; // 总共的边数

        private isVisited: boolean[]; // 顶点是否被访问过

        constructor(vertex: number) {
            this.vertexs = new Array<string>();

            this.isVisited = new Array<boolean>(vertex);
            this.edges = new Array<Array<number>>(vertex);
            for (let i = 0; i < this.edges.length; i++) {
                this.edges[i] = new Array<number>(vertex);
                for (let j = 0; j < this.edges[i].length; j++) {
                    this.edges[i][j] = 0; // 初始化权值都是 0
                }
            }
            this.numberOfEdges = 0;
        }

        /**
         * 深度搜索
         */
        public dfs() :void{
            for (let index = 0; index < this.edges.length; index++) { // for循环查找所有节点
                if(! this.isVisited[index]){

                    this.dfsSearch(this.isVisited, index);
                }
            }
        }

        public dfsSearch(_isVisited: boolean[], row: number): void {

            console.log(this.getVertexName(row) +" -- >");
            let first = this.getFirstNeightbour(row);
            _isVisited[row] = true;
            while(first != -1){
                if(! _isVisited[first]){
                    this.dfsSearch(_isVisited, first);
                }
                first = this.getNextNeightbour(row, first);
            }
        }

        /** 获取下一个顶点,通过startCol来确定起始的位置,减少多余的操作 */
        private getNextNeightbour(row: number, startCol: number) : number{
            for (let index = startCol+1; index < this.edges[row].length; index++) {
                if (this.edges[row][index] > 0) {
                    return index;
                }
            }
            return -1;
        }
        
        /** 查找第一个邻近的顶点 */
        private getFirstNeightbour(row: number): number {
            for (let index = 0; index < this.edges[row].length; index++) {
                if (this.edges[row][index] > 0) {
                    return index;
                }
            }
            return -1;
        }

        public getEdgesWeight(v1: number, v2: number): number {
            return this.edges[v1][v2];
        }

        public printMap(): void {
            console.log("地图打印: -------------------------------");
            console.table(this.edges);
            for (const rows of this.edges) {
            }
        }

        /**
         * 添加顶点
         * @param vertex 顶点字符串
         */
        public addVertex(vertex: string): void {
            this.vertexs.push(vertex);
        }

        /**
         * 插入一条边
         * @param v1 顶点一
         * @param v2 顶点二
         * @param weight 权重 或者  你需要的边长路径之类的
         */
        public insertEdge(v1: number, v2: number, weight: number): void {
            if (!this.edges[v1]) {
                this.edges[v1] = new Array<number>(this.getVertexLen());
            }
            if (!this.edges[v2]) {
                this.edges[v2] = new Array<number>(this.getVertexLen());
            }
            this.edges[v1][v2] = weight;
            this.edges[v2][v1] = weight;
            this.numberOfEdges++;
        }

        public getVertexLen(): number {
            return this.vertexs.length;
        }

        public getVertexName(index: number): string {
            return this.vertexs[index];
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值