图与树,链表的区别
链表是线性数据结构,常见的链表有单向链表,双向链表,有环链表。
链表的每个元素都有一个next指针,指向下一个元素。双向两边还有一个previous指针,指向上一个元素。这类似我们在一个网站上注册账号信息一样,可以点击下一步,也可以点击上一步。
树结构有很多种,二叉树,234树,红黑树等等。
树有个很明显的特点就是,每个节点都可以找到他的子节点,但是从子节点却不能找到他的父节点。每个节点都可以被当做根节点。而且不能有环。
再看图结构
有环无向,或者说是双向。
看起来也是乱七八糟的。图还有一个名字叫拓补结构。
图的深度优先搜索DFS
图的DFS和树不同,因为图有环而树没得。
function Node(value){
this.value = value;
this.neighbor = [];
}
const a = new Node('A'),
b = new Node('B'),
c = new Node('C'),
d = new Node('D'),
e = new Node('E');
a.neighbor.push(b,c);
b.neighbor.push(a,c,d);
c.neighbor.push(a,b,d);
d.neighbor.push(b,c,e);
e.neighbor.push(d);
function search(node, target, path = []){
if(node === null) {
return false;
}
if (path.includes(node)) {
false
}
path.push(node);
if(node.neighbor.length === 0) {
return false;
}
if(node.value === target) {
return true;
}
let result = false;
for (const item of node.neighbor) {
result = search(item, target, path)
}
return result;
}
图的广度优先搜素BFS
思路就是给点一个节点,判断节点是否相等,如果不相等, 收集这个节点的所有邻居,递归邻居查找
function bsf(nodes, target, path = []){
if(nodes.length === 0 || nodes === null) {
return false;
}
const neighbors = []
for (const item of nodes) {
if(path.includes(item)){
continue;
} else {
path.push(item)
if(item.value === target) {
return true;
} else {
neighbors.push(...item.neighbor);
}
}
}
return bsf(neighbors, target, path)
}