que-es-un-grafo

What are Graphs and How to Use Them

  • 9 min

A GRAPH is a mathematical data structure consisting of a set of vertices (also called nodes) and a set of edges that connect these vertices.

There are several ways to encode a GRAPH. But, conceptually, a graph is formed by a series of nodes.

Each of the nodes:

  • Has its own data “inside”
  • Has relationships with other nodes

The relationships between nodes are made through references. Together, that tangle of nodes and relationships forms the GRAPH as a whole.

curso-programacion-grafo

Something like this, but not so fancy

GRAPHs are an elegant way to model relationships between objects. This structure is one of the most versatile and powerful. You will find it everywhere.

For example, a graph could represent a social network, where nodes are users and edges denote friendships or connections. In this way, you could recommend friends or content to users based on the graph.

Another example, a navigation system like Google Maps, where each node represents a location, and the possible relationships. path. You could find the shortest route using algorithms like Dijkstra.

Or, in a software development project, a graph could represent the dependencies between different modules or packages. This way you could find circular references, version conflicts, etc.

In short, you will find graphs everywhere. In fact, other structures like trees or linked lists are simplifications of graphs.

Graph Examples

Graphs are essential for solving a variety of problems in programming, such as finding the shortest path between two points, detecting cycles in a system, or modeling complex relationships.

using System;
using System.Collections.Generic;

public class Node
{
    public string Value { get; set; }
    public List<Node> Parents { get; set; }
    public List<Node> Children { get; set; }

    public Node(string value)
    {
        Value = value;
        Parents = new List<Node>();
        Children = new List<Node>();
    }

    public void AddParent(Node parent)
    {
        Parents.Add(parent);
    }

    public void AddChild(Node child)
    {
        Children.Add(child);
    }
}

public class Graph
{
    private Dictionary<string, Node> Nodes { get; set; }

    public Graph()
    {
        Nodes = new Dictionary<string, Node>();
    }

    public void AddNode(string value)
    {
        if (!Nodes.ContainsKey(value))
        {
            Nodes[value] = new Node(value);
        }
    }

    public void AddEdge(string parentValue, string childValue)
    {
        AddNode(parentValue);
        AddNode(childValue);

        Node parent = Nodes[parentValue];
        Node child = Nodes[childValue];

        parent.AddChild(child);
        child.AddParent(parent);
    }

    public Node GetNode(string value)
    {
        if (Nodes.ContainsKey(value))
        {
            return Nodes[value];
        }
        else
        {
            return null;
        }
    }

    public void PrintGraph()
    {
        foreach (var kvp in Nodes)
        {
            Node node = kvp.Value;
            string parents = string.Join(", ", node.Parents.ConvertAll(n => n.Value));
            string children = string.Join(", ", node.Children.ConvertAll(n => n.Value));
            Console.WriteLine($"Node: {node.Value}, Parents: [{parents}], Children: [{children}]");
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        Graph myGraph = new Graph();

        myGraph.AddEdge("A", "B");
        myGraph.AddEdge("A", "C");
        myGraph.AddEdge("B", "D");
        myGraph.AddEdge("C", "D");
        myGraph.AddEdge("D", "E");
        myGraph.AddEdge("E", "F");
        myGraph.AddEdge("F", "G");

        Console.WriteLine("Graph:");
        myGraph.PrintGraph();

        Node nodeC = myGraph.GetNode("C");
        if (nodeC != null)
        {
            Console.WriteLine($"\nNode 'C' has parents: {string.Join(", ", nodeC.Parents.ConvertAll(n => n.Value))}");
            Console.WriteLine($"Node 'C' has children: {string.Join(", ", nodeC.Children.ConvertAll(n => n.Value))}");
        }
        else
        {
            Console.WriteLine("\nNode 'C' does not exist in the graph.");
        }
    }
}
Copied!
#include <iostream>
#include <vector>
#include <unordered_map>
#include <string>

class Node {
public:
    std::string value;
    std::vector<Node*> parents;
    std::vector<Node*> children;

    Node(std::string val) : value(val) {}

    void addParent(Node* parent) {
        parents.push_back(parent);
    }

    void addChild(Node* child) {
        children.push_back(child);
    }
};

class Graph {
private:
    std::unordered_map<std::string, Node*> nodes;

public:
    void addNode(std::string value) {
        if (nodes.find(value) == nodes.end()) {
            nodes[value] = new Node(value);
        }
    }

    void addEdge(std::string parentValue, std::string childValue) {
        addNode(parentValue);
        addNode(childValue);

        Node* parent = nodes[parentValue];
        Node* child = nodes[childValue];

        parent->addChild(child);
        child->addParent(parent);
    }

    Node* getNode(std::string value) {
        if (nodes.find(value) != nodes.end()) {
            return nodes[value];
        }
        return nullptr;
    }

    void printGraph() {
        for (auto& kvp : nodes) {
            Node* node = kvp.second;
            std::cout << "Node: " << node->value << ", Parents: [";
            for (auto& parent : node->parents) {
                std::cout << parent->value << " ";
            }
            std::cout << "], Children: [";
            for (auto& child : node->children) {
                std::cout << child->value << " ";
            }
            std::cout << "]" << std::endl;
        }
    }

    ~Graph() {
        for (auto& kvp : nodes) {
            delete kvp.second;
        }
    }
};

int main() {
    Graph myGraph;

    myGraph.addEdge("A", "B");
    myGraph.addEdge("A", "C");
    myGraph.addEdge("B", "D");
    myGraph.addEdge("C", "D");
    myGraph.addEdge("D", "E");
    myGraph.addEdge("E", "F");
    myGraph.addEdge("F", "G");

    std::cout << "Graph:" << std::endl;
    myGraph.printGraph();

    Node* nodeC = myGraph.getNode("C");
    if (nodeC != nullptr) {
        std::cout << "\nNode 'C' has parents: ";
        for (auto& parent : nodeC->parents) {
            std::cout << parent->value << " ";
        }
        std::cout << "\nNode 'C' has children: ";
        for (auto& child : nodeC->children) {
            std::cout << child->value << " ";
        }
        std::cout << std::endl;
    } else {
        std::cout << "\nNode 'C' does not exist in the graph." << std::endl;
    }

    return 0;
}
Copied!
class Node {
    constructor(value) {
        this.value = value;
        this.parents = [];
        this.children = [];
    }

    addParent(parent) {
        this.parents.push(parent);
    }

    addChild(child) {
        this.children.push(child);
    }
}

class Graph {
    constructor() {
        this.nodes = {};
    }

    addNode(value) {
        if (!this.nodes[value]) {
            this.nodes[value] = new Node(value);
        }
    }

    addEdge(parentValue, childValue) {
        this.addNode(parentValue);
        this.addNode(childValue);

        const parent = this.nodes[parentValue];
        const child = this.nodes[childValue];

        parent.addChild(child);
        child.addParent(parent);
    }

    getNode(value) {
        return this.nodes[value] || null;
    }

    printGraph() {
        for (const value in this.nodes) {
            const node = this.nodes[value];
            const parents = node.parents.map(parent => parent.value).join(", ");
            const children = node.children.map(child => child.value).join(", ");
            console.log(`Node: ${node.value}, Parents: [${parents}], Children: [${children}]`);
        }
    }
}

// Creating a graph and adding nodes and edges
const myGraph = new Graph();

myGraph.addEdge("A", "B");
myGraph.addEdge("A", "C");
myGraph.addEdge("B", "D");
myGraph.addEdge("C", "D");
myGraph.addEdge("D", "E");
myGraph.addEdge("E", "F");
myGraph.addEdge("F", "G");

console.log("Graph:");
myGraph.printGraph();

const nodeC = myGraph.getNode("C");
if (nodeC) {
    console.log(`\nNode 'C' has parents: ${nodeC.parents.map(parent => parent.value).join(", ")}`);
    console.log(`Node 'C' has children: ${nodeC.children.map(child => child.value).join(", ")}`);
} else {
    console.log("\nNode 'C' does not exist in the graph.");
}

Copied!
class Node:
    def __init__(self, value):
        self.value = value
        self.parents = []
        self.children = []

    def add_parent(self, parent):
        self.parents.append(parent)

    def add_child(self, child):
        self.children.append(child)

class Graph:
    def __init__(self):
        self.nodes = {}

    def add_node(self, value):
        new_node = Node(value)
        self.nodes[value] = new_node
        return new_node

    def add_edge(self, parent, child):
        if parent not in self.nodes:
            self.add_node(parent)
        if child not in self.nodes:
            self.add_node(child)

        self.nodes[parent].add_child(child)
        self.nodes[child].add_parent(parent)

    def get_node(self, value):
        if value in self.nodes:
            return self.nodes[value]
        else:
            return None

    def print_graph(self):
        for value, node in self.nodes.items():
            parents = ', '.join(node.parents)
            children = ', '.join(node.children)
            print(f"Node: {value}, Parents: [{parents}], Children: [{children}]")

# Creating a graph and adding nodes and edges
my_graph = Graph()

my_graph.add_edge('A', 'B')
my_graph.add_edge('A', 'C')
my_graph.add_edge('B', 'D')
my_graph.add_edge('C', 'D')
my_graph.add_edge('D', 'E')
my_graph.add_edge('E', 'F')
my_graph.add_edge('F', 'G')

# Printing the graph
print("Graph:")
my_graph.print_graph()

# Accessing a specific node
node_c = my_graph.get_node('C')
if node_c:
    print("\nNode 'C' has parents:", node_c.parents)
    print("Node 'C' has children:", node_c.children)
else:
    print("\nNode 'C' does not exist in the graph.")
Copied!