JS實現圖的創建和遍歷


圖分為無向圖和有向圖 

圖的存儲結構有鄰接矩陣、鄰接表、十字鏈表、鄰接多重表這四種,最常用的是前兩種

本篇主要是利用鄰接矩陣實現無向圖的創建和遍歷(深度優先、廣度優先),深度優先其實就是二叉樹里的前序遍歷

 

  

 

 

利用鄰接矩陣(邊數組)創建圖

let scanf = require('scanf');
//定義鄰接矩陣
let Arr2 = [
    [0, 1, 0, 0, 0, 1, 0, 0, 0],
    [1, 0, 1, 0, 0, 0, 1, 0, 1],
    [0, 1, 0, 1, 0, 0, 0, 0, 1],
    [0, 0, 1, 0, 1, 0, 1, 1, 1],
    [0, 0, 0, 1, 0, 1, 0, 1, 0],
    [1, 0, 0, 0, 0, 0, 1, 0, 0],
    [0, 1, 0, 1, 0, 1, 0, 1, 0],
    [0, 0, 0, 1, 1, 0, 1, 0, 0],
    [0, 1, 1, 1, 0, 0, 0, 0, 0],
]

let numVertexes = 9, //定義頂點數
    numEdges = 14; //定義邊數

// 定義圖結構  
function MGraph() {
    this.vexs = []; //頂點表
    this.arc = []; // 鄰接矩陣,可看作邊表
    this.numVertexes = null; //圖中當前的頂點數
    this.numEdges = null; //圖中當前的邊數
}
let G = new MGraph(); //創建圖使用

//創建圖
function createMGraph() {
    G.numVertexes = numVertexes; //設置頂點數
    G.numEdges = numEdges; //設置邊數

    //錄入頂點信息
    for (let i = 0; i < G.numVertexes; i++) {
        G.vexs[i] = scanf('%s'); //String.fromCharCode(i + 65); ascii碼轉字符
    }
    console.log(G.vexs) //打印頂點

    //鄰接矩陣初始化
    for (let i = 0; i < G.numVertexes; i++) {
        G.arc[i] = [];
        for (j = 0; j < G.numVertexes; j++) {
            G.arc[i][j] = Arr2[i][j]; //INFINITY; 
        }
    }

    /**以下是手動錄入的方式 */
    // for (let k = 0; k < G.numEdges; k++) {
    //     console.log('輸入邊(vi,vj)上的下標i,下標j和權w:');
    //     let rlt = scanf('%d,%d,%d');
    //     let i = rlt[0], j = rlt[1], w = rlt[2];
    //     G.arc[i][j] = w;
    //     G.arc[j][i] = G.arc[i][j]; //無向圖,矩陣對稱
    // }

    console.log(G.arc); //打印鄰接矩陣
}

深度優先遍歷

let visited = []; //訪問標志數組,遍歷時使用

//鄰接矩陣的深度優先遞歸算法
function DFS(i) {
    visited[i] = true;
    console.log('打印頂點:', G.vexs[i]) //打印頂點 ,也可以其他操作
    for (let j = 0; j < G.numVertexes; j++) {
        if (G.arc[i][j] == 1 && !visited[j]) {
            console.log(G.vexs[i], '->', G.vexs[j])
            DFS(j) //對未訪問的頂點進行遞歸
        }
    }
}
//鄰接矩陣的深度遍歷操作
function DFSTraverse() {
    for (let i = 0; i < G.numVertexes; i++) {
        visited[i] = false;
    }
    for (let i = 0; i < G.numVertexes; i++) {
        if (!visited[i])
            DFS(i)
    }
}

廣度優先遍歷

//鄰接矩陣的廣度遍歷算法
function BFSTraverse() {
    let queue = []; //初始化隊列
    for (let i = 0; i < G.numVertexes; i++) {
        visited[i] = false;
    }
    for (let i = 0; i < G.numVertexes; i++) { //對每一個頂點做循環
        if (!visited[i]) { //如果沒有訪問過就處理
            visited[i] = true;
            console.log('打印頂點:', G.vexs[i]) //也可以是其他操作
            queue.push(i); //將此頂點入隊列
            while (queue.length != 0) { //當前隊列不為空
                queue.shift();
                for (let j = 0; j < G.numVertexes; j++) {
                    //判斷其他頂點若與當前頂點存在邊且未訪問過
                    if (G.arc[i][j] == 1 && !visited[j]) {
                        visited[j] = true;
                        console.log(G.vexs[i], '->', G.vexs[j])
                        console.log('打印頂點:', G.vexs[j])
                        queue.push(j) //將此頂點放入隊列
                    }
                }
            }
        }
    }
}

運行:

console.log('**********創建圖結構**********');
createMGraph();
console.log('**********廣度優先遍歷**********');
DFSTraverse();
console.log('**********廣度優先遍歷**********');
BFSTraverse();

結果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM