圖是由具有邊的節(jié)點集合組成的數(shù)據(jù)結(jié)構(gòu)臣淤。圖可以是有向的或者是無向的。
有向圖包含功能類似于單行道的邊晌姚。邊緣從一個節(jié)點流向另一個節(jié)點。
比如歇竟,你可能有一個(關(guān)于)人物和電影的圖表挥唠,其中每個人可以有多個喜歡的電影,但是電影沒有喜歡的人焕议。
無向圖包含雙向流動的邊緣宝磨,類似于雙向道路,兩個方向都有交通盅安。
比如唤锉,你可能有一個寵物圖表,其中每只寵物都有一個所有者别瞭,每個所有者都有一只寵物窿祥。
備注:(下面)雙向箭頭代表一條邊,但是為了顯而易見蝙寨,我繪制了兩條箭頭晒衩。
圖(graph)中沒有明確的信息層次結(jié)構(gòu)嗤瞎。
方法
我們將創(chuàng)建一個(關(guān)于)人和冰淇凌口味的圖表。這將是一個有向圖听系,因為人們可以喜歡某些口味贝奇,但是味道可不喜歡人。
我們將創(chuàng)建三個類:
PersonNode
IceCreamFlavorNode
Graph
PersonNode
PersonNode
類將接受一個參數(shù):一個人的名字靠胜。這將作為其標識符掉瞳。
PersonNode
構(gòu)造函數(shù)將包含兩個屬性:
-
name
:唯一標識符 -
favoriteFlavors
:關(guān)于IceCreamFlavorNodes的數(shù)組
另外,PersonNode
類包含一個方法:addFlavor
浪漠。這將傳入一個參數(shù)陕习,一個IceCreamFlavorNode
對象,并將其添加到數(shù)組favoriteFlavors
中郑藏。
類的定義如下所示:
class PersonNode {
constructor(name) {
this.name = name;
this.favoriteFlavors = [];
}
addFlavor(flavor) {
this.favoriteFlavors.push(flavor);
}
}
IceCreamFlavorNode
IceCreamFlavorNode
類將傳入一個參數(shù):冰淇凌口味衡查。這將作為其標識符瘩欺。
這個類不需要包含任何方法必盖,因為這是一個無向圖,數(shù)據(jù)是從person
流向flavors
俱饿,但是不會回流歌粥。
這個類的定義如下:
class IceCreamFlavorNode {
constructor(flavor) {
this.flavor = flavor;
}
}
Graph
Graph
類不接受任何參數(shù),但是其構(gòu)造函數(shù)將包含三個屬性:
-
peopleNodes
:人物節(jié)點數(shù)組拍埠。 -
iceCreamFlavorNodes
:冰淇凌口味節(jié)點數(shù)組失驶。 -
edges
:包含PersonNodes
和IceCreamFlavorNodes
之間的邊緣數(shù)組。
Graph
類將包含六個方法:
-
addPersonNode(name)
:接受一個參數(shù)枣购,一個人的名字嬉探,創(chuàng)建一個具有此名字的PersonNode
對象,并將其推送到peopleNodes
數(shù)組棉圈。 -
addIceCreamFlavorNode(flavor)
:接受一個參數(shù)涩堤,一個冰淇凌口味,創(chuàng)建一個具有這種口味的IceCreamFlavorNode
對象分瘾,并將其推送到iceCreamFlavorNodes
數(shù)組中构诚。 -
getPerson(name)
:接受一個參數(shù)混槐,一個人名字,并返回該人的節(jié)點。 -
getFlavor(flavor)
:接受一個參數(shù)碌补,一個冰淇凌口味,并返回該口味的節(jié)點凄鼻。 -
addEdge(personName, flavorName)
:接受兩個參數(shù)肢础,一個人的名稱和一個冰淇凌口味,檢索兩個節(jié)點肴掷,將flavor
添加到人的favoriteFlavors
數(shù)組敬锐,并將邊推送到edge
數(shù)組辞嗡。 -
print()
:簡單打印出peopleNodes
數(shù)組中的每個人,以及他們最喜歡的冰淇凌口味滞造。
類的定義如下所示:
class Graph {
constructor() {
this.peopleNodes = [];
this.iceCreamFlavorNodes = [];
this.edges = [];
}
addPersonNode(name) {
this.peopleNodes.push(new PersonNode(name));
}
addIceCreamFlavorNode(flavor) {
this.iceCreamFlavorNodes.push(new IceCreamFlavorNode(flavor));
}
getPerson(name) {
return this.peopleNodes.find(person => person.name === name);
}
getFlavor(flavor) {
return this.iceCreamFlavorNodes.find(flavor => flavor === flavor);
}
addEdge(personName, flavorName) {
const person = this.getPerson(personName);
const flavor = this.getFlavor(flavorName);
person.addFlavor(flavor);
this.edges.push(`${personName} - ${flavorName}`);
}
print() {
return this.peopleNodes.map(({ name, favoriteFlavors }) => {
return `${name} => ${favoriteFlavors.map(flavor => `${flavor.flavor},`).join(' ')}`;
}).join('\n')
}
}
虛擬數(shù)據(jù)
現(xiàn)在续室,我們有了三個類,我們可以添加一些數(shù)據(jù)并測試它們:
const graph = new Graph(true);
graph.addPersonNode('Emma');
graph.addPersonNode('Kai');
graph.addPersonNode('Sarah');
graph.addPersonNode('Maranda');
graph.addIceCreamFlavorNode('Chocolate Chip');
graph.addIceCreamFlavorNode('Strawberry');
graph.addIceCreamFlavorNode('Cookie Dough');
graph.addIceCreamFlavorNode('Vanilla');
graph.addIceCreamFlavorNode('Pistachio');
graph.addEdge('Emma', 'Chocolate Chip');
graph.addEdge('Emma', 'Cookie Dough');
graph.addEdge('Emma', 'Vanilla');
graph.addEdge('Kai', 'Vanilla');
graph.addEdge('Kai', 'Strawberry');
graph.addEdge('Kai', 'Cookie Dough');
graph.addEdge('Kai', 'Chocolate Chip');
graph.addEdge('Kai', 'Pistachio');
graph.addEdge('Maranda', 'Vanilla');
graph.addEdge('Maranda', 'Cookie Dough');
graph.addEdge('Sarah', 'Strawberry');
console.log(graph.print());
下面是我們有向圖看起來類似(的樣子):
如果你想看完整的代碼谒养,到我的CodePen上查看挺狰。
后話
原文:https://dev.to/emmawedekind/creating-graphs-with-javascript-4efm
更多內(nèi)容:https://github.com/reng99/blogs