圖分為無向圖和有向圖
圖的存儲結構有鄰接矩陣、鄰接表、十字鏈表、鄰接多重表這四種,最常用的是前兩種
本篇主要是利用鄰接矩陣實現無向圖的創建和遍歷(深度優先、廣度優先),深度優先其實就是二叉樹里的前序遍歷
利用鄰接矩陣(邊數組)創建圖
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();
結果: