Este projeto consiste na implementação de 8 estruturas de dados diferentes em JavaScript. Cada estrutura de dados é projetada para resolver problemas específicos e proporcionar uma base sólida para o desenvolvimento de software.
-
Lista Encadeada
- Descrição: Uma lista de elementos conectados, onde cada elemento aponta para o próximo na sequência.
-
Pilha
- Descrição: Uma coleção de elementos com operações Last In, First Out (LIFO).
-
Fila
- Descrição: Uma coleção de elementos com operações First In, First Out (FIFO).
-
Árvore Binária
- Descrição: Uma estrutura hierárquica onde cada nó tem, no máximo, dois filhos.
-
Tabela Hash
- Descrição: Uma estrutura que mapeia chaves para valores, proporcionando acesso rápido aos dados.
-
Grafo
- Descrição: Uma representação de conexões entre diferentes entidades.
Aqui está um exemplo de como implementar Grafos em JavaScript:
// Exemplo de uso de Grafos
const Dictionary = Map;
const Queue = () => {
let storage = [];
return {
dequeue: () => storage.shift(),
isEmpty: () => storage.length === 0,
enqueue: (value) => storage.push(value),
};
};
class Graph {
#adjList;
#vertices;
#isDirected;
constructor(isDirected = false) {
this.#vertices = [];
this.#isDirected = isDirected;
this.#adjList = new Dictionary();
}
addVertex(vertex) {
if (this.#vertices.includes(vertex)) return;
this.#vertices.push(vertex);
this.#adjList.set(vertex, []);
}
addEdge(mainVertex, otherVertex) {
if (!this.#adjList.has(mainVertex)) this.addVertex(mainVertex);
if (!this.#adjList.has(otherVertex)) this.addVertex(otherVertex);
this.#adjList.get(mainVertex).push(otherVertex);
if (this.#isDirected) return;
this.#adjList.get(otherVertex).push(mainVertex);
}
toString() {
this.#adjList.forEach((value, key) =>
console.log(`${key}: ${JSON.stringify(value).replace(/,/g, ", ")}`)
);
}
// get all vertices and the shortest path from a vertex to all remaining
breadthFirstSearch(vertex = this.#vertices[0]) {
const queue = Queue();
const allVertex = [];
const visited = Object.create(null);
const distances = Object.create(null);
const predecessors = Object.create(null);
queue.enqueue(vertex);
for (const v of this.#vertices) {
distances[v] = 0;
visited[v] = false;
predecessors[v] = null;
}
while (!queue.isEmpty()) {
const dequeuedVertex = queue.dequeue();
const neighbors = this.#adjList.get(dequeuedVertex);
visited[dequeuedVertex] = true;
for (let neighbor of neighbors) {
if (!visited[neighbor]) {
visited[neighbor] = true;
queue.enqueue(neighbor);
predecessors[neighbor] = dequeuedVertex;
distances[neighbor] = distances[dequeuedVertex] + 1;
}
}
allVertex.push(dequeuedVertex);
}
return JSON.parse(
JSON.stringify({
distances,
allVertex,
predecessors,
})
);
}
depthFirstSearch() {
const allVertex = [];
const visited = Object.create(null);
for (const v of this.#vertices) {
visited[v] = false;
}
function recursive(vertex) {
visited[vertex] = true;
allVertex.push(vertex);
const neighbors = this.#adjList.get(vertex);
for (const neighbor of neighbors) {
if (!visited[neighbor]) {
recursive.bind(this)(neighbor);
}
}
}
for (const vertex of this.#vertices) {
if (!visited[vertex]) recursive.bind(this)(vertex);
}
return JSON.parse(
JSON.stringify({
allVertex,
})
);
}
dijkstra(matrix, startVertex) {
const visited = [];
const distances = [];
const { length } = matrix;
for (let index = 0; index < length; index++) {
visited[index] = false;
distances[index] = Infinity;
}
distances[startVertex] = 0;
function minDistance() {
let minIndex = -1;
let min = Infinity;
for (let index = 0; index < distances.length; index++) {
if (visited[index] === false && distances[index] <= min) {
min = distances[index];
minIndex = index;
}
}
return minIndex;
}
for (let _ = 0; _ < length - 1; _++) {
const minDistanceIndex = minDistance.apply(this);
visited[minDistanceIndex] = true;
for (let index = 0; index < length; index++) {
if (
!visited[index] &&
matrix[minDistanceIndex][index] !== 0 &&
distances[minDistanceIndex] !== Infinity &&
distances[minDistanceIndex] + matrix[minDistanceIndex][index] <
distances[index]
) {
distances[index] =
distances[minDistanceIndex] + matrix[minDistanceIndex][index];
}
}
}
return distances;
}
get vertices() {
return this.#vertices;
}
get adjList() {
return this.#adjList;
}
}
function buildGraph() {
const graph = new Graph();
const vertices = ["A", "B", "C", "D", "E", "F", "G", "H", "I"];
for (let vertex of vertices) {
graph.addVertex(vertex);
}
const vertexAndEdgePairs = [
["A", "B"],
["A", "C"],
["A", "D"],
["C", "D"],
["C", "G"],
["D", "G"],
["D", "H"],
["B", "E"],
["B", "F"],
["E", "I"],
];
for (const vertexAndEdgePair of vertexAndEdgePairs) {
graph.addEdge(vertexAndEdgePair[0], vertexAndEdgePair[1]);
}
return graph;
}
const graph = buildGraph();
graph.toString();
/*
Output:
A: ["B", "C", "D"]
B: ["A", "E", "F"]
C: ["A", "D", "G"]
D: ["A", "C", "G", "H"]
E: ["B", "I"]
F: ["B"]
G: ["C", "D"]
H: ["D"]
I: ["E"]
*/
console.log(graph.breadthFirstSearch());
/*
Output:
{
distances: { A: 0, B: 1, C: 1, D: 1, E: 2, F: 2, G: 2, H: 2, I: 3 },
allVertex: [
'A', 'B', 'C',
'D', 'E', 'F',
'G', 'H', 'I'
],
predecessors: {
A: null,
B: 'A',
C: 'A',
D: 'A',
E: 'B',
F: 'B',
G: 'C',
H: 'D',
I: 'E'
}
}
*/
console.log(graph.depthFirstSearch());
/*
Output:
{
allVertex: [
'A', 'B', 'E',
'I', 'F', 'C',
'D', 'G', 'H'
]
}
*/
console.log(
graph.dijkstra(
[
[0, 2, 4, 0, 0, 0],
[0, 0, 1, 4, 2, 0],
[0, 0, 0, 0, 3, 0],
[0, 0, 0, 0, 0, 2],
[0, 0, 0, 3, 0, 2],
[0, 0, 0, 0, 0, 0],
],
0
)
);
/*
Output:
[ 0, 2, 3, 6, 4, 6 ]
*/