Files
mermaid/packages/mermaid-flowchart-v3/src/render-utils.js
2022-12-16 16:28:24 +01:00

120 lines
2.7 KiB
JavaScript

export const findCommonAncestorCoPilot = (id1, id2, treeData) => {
const { parentById, childrenById } = treeData;
const parents1 = [];
const parents2 = [];
let cnt = 0;
let currentId = id1;
while (currentId) {
parents1.push(currentId);
currentId = parentById[currentId];
cnt++;
if (cnt > 200) {
throw new Error('Infinite loop detected!');
}
}
currentId = id2;
while (currentId) {
parents2.push(currentId);
currentId = parentById[currentId];
cnt++;
if (cnt > 200) {
throw new Error('Infinite loop detected!');
}
}
let commonAncestor = 'root';
while (parents1.length && parents2.length) {
cnt++;
if (cnt > 200) {
throw new Error('Infinite loop detected!');
}
const p1 = parents1.pop();
const p2 = parents2.pop();
if (p1 === p2) {
commonAncestor = p1;
} else {
break;
}
}
return commonAncestor;
};
export const findCommonAncestor = (id1, id2, treeData) => {
const { parentById } = treeData;
const visited = new Set();
let currentId = id1;
while (currentId) {
visited.add(currentId);
if (currentId === id2) {
return currentId;
}
currentId = parentById[currentId];
}
currentId = id2;
while (currentId) {
if (visited.has(currentId)) {
return currentId;
}
currentId = parentById[currentId];
}
return 'root';
};
export const findCommonAncestorKnut = (id1, id2, treeData) => {
const { parentById, childrenById } = treeData;
const parents1 = [];
const parents2 = [];
let cnt = 0;
let currentId = id1;
while (currentId) {
parents1.push(currentId);
currentId = parentById[currentId];
cnt++;
if (cnt > 200) {
throw new Error('Infinite loop detected!');
}
}
currentId = id2;
while (currentId) {
parents2.push(currentId);
currentId = parentById[currentId];
if (currentId === 'root') {
return 'root';
}
if (parents1.includes(currentId)) {
return currentId;
}
cnt++;
if (cnt > 200) {
throw new Error('Infinite loop detected!');
}
}
return 'root';
};
export const findCommonAncestorRecursive = (id1, id2, treeData) => {
const { parentById, childrenById } = treeData;
// Base case: return the current node if it is the common ancestor
if (id1 === id2) {
return id1;
}
// Recursive case: search for the common ancestor in the parent nodes
const parent1 = parentById[id1];
const parent2 = parentById[id2];
if (parent1 && parent2) {
return findCommonAncestor(parent1, parent2, treeData);
}
// Edge case: one of the nodes is the root of the tree
if (parent1) {
return parent1;
}
if (parent2) {
return parent2;
}
return 'root';
};