class Grapg<T> {
// 用於存儲所有的頂點
verteces: T[] = [];
// 用於存儲所有的邊 採用鄰接表的形式
adjList: Map<T, T[]> = new Map();
// 添加頂點
addVertex(v: T) {
this.verteces.push(v);
// 初始化頂點的鄰接表
this.adjList.set(v, []);
}
// 添加邊
addEdge(v: T, w: T) {
// 有向圖 只需要添加單向的邊
this.adjList.get(v)?.push(w);
// 無向圖 需要添加反向的邊
this.adjList.get(w)?.push(v);
}
// 打印圖
printEdges() {
// 遍歷所有的頂點
this.verteces.forEach((vertex) => {
// 打印頂點和它的鄰接表
console.log(`${vertex} -> ${this.adjList.get(vertex)?.join(' ')}`);
});
}
// 廣度優先遍歷
BFS() {
if (this.verteces.length === 0) return;
const visited = new Set<T>(); // 用於存儲已經訪問過的頂點
visited.add(this.verteces[0]); // 從第一個頂點開始遍歷
const queue = [this.verteces[0]]; // 用於存儲待訪問的頂點
// 隊列不爲空時
while (queue.length) {
const v = queue.shift()!; // 取出隊列的第一個頂點
console.log(v); // 打印頂點
const vEdges = this.adjList.get(v); // 獲取該頂點的鄰接表
// 如果沒有鄰接表 則跳過
if (!vEdges) continue;
// 從前往後遍歷
for (const e of vEdges) {
// 如果沒有訪問過 就入隊列
if (!visited.has(e)) {
visited.add(e);
queue.push(e);
}
}
}
}
// 深度優先遍歷
DFS() {
if (this.verteces.length === 0) return;
const visited = new Set<T>(); // 用於存儲已經訪問過的頂點
visited.add(this.verteces[0]); // 從第一個頂點開始遍歷
const stack = [this.verteces[0]]; // 用於存儲待訪問的頂點
// 棧不爲空時
while (stack.length) {
const v = stack.pop()!; // 取出棧頂的頂點
console.log(v); // 打印頂點
const vEdges = this.adjList.get(v); // 獲取該頂點的鄰接表
if (!vEdges) return; // 如果沒有鄰接表 則跳過
// 從後往前遍歷
for (let i = vEdges.length - 1; i >= 0; i--) {
const e = vEdges[i]; // 獲取頂點
// 如果沒有訪問過 就入棧
if (!visited.has(e)) {
stack.push(e);
visited.add(e);
}
}
}
}
}
const graph = new Grapg<string>();
// 添加A-I的頂點
for (let i = 0; i < 9; i++) {
graph.addVertex(String.fromCharCode(65 + i));
}
// 添加邊
graph.addEdge('A', 'B');
graph.addEdge('A', 'C');
graph.addEdge('A', 'D');
graph.addEdge('C', 'D');
graph.addEdge('C', 'G');
graph.addEdge('D', 'G');
graph.addEdge('D', 'H');
graph.addEdge('B', 'E');
graph.addEdge('B', 'F');
graph.addEdge('E', 'I');
graph.printEdges();
console.log('BFS');
graph.BFS();
console.log('DFS');
graph.DFS();
【數據結構與算法】TypeScript 實現圖結構
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.