Графы можно представить несколькими способами: матрица смежности и список смежности. Ниже приведены примеры реализации для разных языков программирования.
# Граф с 4 вершинами (0, 1, 2, 3)
# Ребра: 0-1 (вес 2), 0-2 (вес 5), 1-2 (вес 1), 2-3 (вес 3)
class Graph:
    def __init__(self, num_vertices):
        self.num_vertices = num_vertices
        # Инициализация матрицы смежности нулями
        self.adj_matrix = [[0] * num_vertices for _ in range(num_vertices)]
    
    def add_edge(self, u, v, weight=1):
        # Добавление ребра между вершинами u и v с весом
        self.adj_matrix[u][v] = weight
        self.adj_matrix[v][u] = weight  # Для неориентированного графа
    
    def display(self):
        # Вывод матрицы смежности
        for row in self.adj_matrix:
            print(row)
# Создание графа
g = Graph(4)
g.add_edge(0, 1, 2)
g.add_edge(0, 2, 5)
g.add_edge(1, 2, 1)
g.add_edge(2, 3, 3)
# Вывод матрицы смежности
print("Матрица смежности:")
g.display()Матрица смежности представляет собой двумерный список, где adj_matrix[i][j] содержит вес ребра между вершинами i и j. Если ребра нет, значение равно 0.
# Граф с 4 вершинами (0, 1, 2, 3)
# Ребра: 0-1 (вес 2), 0-2 (вес 5), 1-2 (вес 1), 2-3 (вес 3)
class Graph:
    def __init__(self, num_vertices):
        self.num_vertices = num_vertices
        # Инициализация списка смежности пустыми словарями
        self.adj_list = [{} for _ in range(num_vertices)]
    
    def add_edge(self, u, v, weight=1):
        # Добавление ребра между вершинами u и v с весом
        self.adj_list[u][v] = weight
        self.adj_list[v][u] = weight  # Для неориентированного графа
    
    def display(self):
        # Вывод списка смежности
        for i, neighbors in enumerate(self.adj_list):
            print(f"{i}: {neighbors}")
# Создание графа
g = Graph(4)
g.add_edge(0, 1, 2)
g.add_edge(0, 2, 5)
g.add_edge(1, 2, 1)
g.add_edge(2, 3, 3)
# Вывод списка смежности
print("Список смежности:")
g.display()Список смежности представляет собой список словарей, где adj_list[i] содержит словарь с ключами - смежными вершинами, и значениями - весами соответствующих ребер.
#include <iostream>
#include <vector>
using namespace std;
class Graph {
private:
    int numVertices;
    vector<vector<int>> adjMatrix;
public:
    Graph(int vertices) : numVertices(vertices) {
        // Инициализация матрицы смежности нулями
        adjMatrix.resize(numVertices, vector<int>(numVertices, 0));
    }
    
    void addEdge(int u, int v, int weight = 1) {
        // Добавление ребра между вершинами u и v с весом
        adjMatrix[u][v] = weight;
        adjMatrix[v][u] = weight; // Для неориентированного графа
    }
    
    void display() {
        // Вывод матрицы смежности
        for (int i = 0; i < numVertices; i++) {
            for (int j = 0; j < numVertices; j++) {
                cout << adjMatrix[i][j] << " ";
            }
            cout << endl;
        }
    }
};
int main() {
    // Граф с 4 вершинами (0, 1, 2, 3)
    // Ребра: 0-1 (вес 2), 0-2 (вес 5), 1-2 (вес 1), 2-3 (вес 3)
    Graph g(4);
    g.addEdge(0, 1, 2);
    g.addEdge(0, 2, 5);
    g.addEdge(1, 2, 1);
    g.addEdge(2, 3, 3);
    
    // Вывод матрицы смежности
    cout << "Матрица смежности:" << endl;
    g.display();
    
    return 0;
}Матрица смежности реализована как вектор векторов. adjMatrix[i][j] содержит вес ребра между вершинами i и j. Если ребра нет, значение равно 0.
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
class Graph {
private:
    int numVertices;
    vector<unordered_map<int, int>> adjList;
public:
    Graph(int vertices) : numVertices(vertices) {
        // Инициализация списка смежности
        adjList.resize(numVertices);
    }
    
    void addEdge(int u, int v, int weight = 1) {
        // Добавление ребра между вершинами u и v с весом
        adjList[u][v] = weight;
        adjList[v][u] = weight; // Для неориентированного графа
    }
    
    void display() {
        // Вывод списка смежности
        for (int i = 0; i < numVertices; i++) {
            cout << i << ": ";
            for (auto& neighbor : adjList[i]) {
                cout << "(" << neighbor.first << ", " << neighbor.second << ") ";
            }
            cout << endl;
        }
    }
};
int main() {
    // Граф с 4 вершинами (0, 1, 2, 3)
    // Ребра: 0-1 (вес 2), 0-2 (вес 5), 1-2 (вес 1), 2-3 (вес 3)
    Graph g(4);
    g.addEdge(0, 1, 2);
    g.addEdge(0, 2, 5);
    g.addEdge(1, 2, 1);
    g.addEdge(2, 3, 3);
    
    // Вывод списка смежности
    cout << "Список смежности:" << endl;
    g.display();
    
    return 0;
}Список смежности реализован как вектор unordered_map, где adjList[i] содержит пары ключ-значение: ключ - смежная вершина, значение - вес ребра.
public class AdjacencyMatrix {
    private int numVertices;
    private int[][] adjMatrix;
    
    public AdjacencyMatrix(int vertices) {
        this.numVertices = vertices;
        // Инициализация матрицы смежности нулями
        this.adjMatrix = new int[numVertices][numVertices];
    }
    
    public void addEdge(int u, int v, int weight) {
        // Добавление ребра между вершинами u и v с весом
        adjMatrix[u][v] = weight;
        adjMatrix[v][u] = weight; // Для неориентированного графа
    }
    
    public void display() {
        // Вывод матрицы смежности
        for (int i = 0; i < numVertices; i++) {
            for (int j = 0; j < numVertices; j++) {
                System.out.print(adjMatrix[i][j] + " ");
            }
            System.out.println();
        }
    }
    
    public static void main(String[] args) {
        // Граф с 4 вершинами (0, 1, 2, 3)
        // Ребра: 0-1 (вес 2), 0-2 (вес 5), 1-2 (вес 1), 2-3 (вес 3)
        AdjacencyMatrix g = new AdjacencyMatrix(4);
        g.addEdge(0, 1, 2);
        g.addEdge(0, 2, 5);
        g.addEdge(1, 2, 1);
        g.addEdge(2, 3, 3);
        
        // Вывод матрицы смежности
        System.out.println("Матрица смежности:");
        g.display();
    }
}Матрица смежности реализована как двумерный массив. adjMatrix[i][j] содержит вес ребра между вершинами i и j. Если ребра нет, значение равно 0.
import java.util.*;
public class AdjacencyList {
    private int numVertices;
    private Map<Integer, Integer>[] adjList;
    
    @SuppressWarnings("unchecked")
    public AdjacencyList(int vertices) {
        this.numVertices = vertices;
        // Инициализация списка смежности
        this.adjList = new HashMap[numVertices];
        for (int i = 0; i < numVertices; i++) {
            adjList[i] = new HashMap<>();
        }
    }
    
    public void addEdge(int u, int v, int weight) {
        // Добавление ребра между вершинами u и v с весом
        adjList[u].put(v, weight);
        adjList[v].put(u, weight); // Для неориентированного графа
    }
    
    public void display() {
        // Вывод списка смежности
        for (int i = 0; i < numVertices; i++) {
            System.out.print(i + ": ");
            for (Map.Entry<Integer, Integer> entry : adjList[i].entrySet()) {
                System.out.print("(" + entry.getKey() + ", " + entry.getValue() + ") ");
            }
            System.out.println();
        }
    }
    
    public static void main(String[] args) {
        // Граф с 4 вершинами (0, 1, 2, 3)
        // Ребра: 0-1 (вес 2), 0-2 (вес 5), 1-2 (вес 1), 2-3 (вес 3)
        AdjacencyList g = new AdjacencyList(4);
        g.addEdge(0, 1, 2);
        g.addEdge(0, 2, 5);
        g.addEdge(1, 2, 1);
        g.addEdge(2, 3, 3);
        
        // Вывод списка смежности
        System.out.println("Список смежности:");
        g.display();
    }
}Список смежности реализован как массив HashMap, где adjList[i] содержит пары ключ-значение: ключ - смежная вершина, значение - вес ребра.
class Graph {
    constructor(numVertices) {
        this.numVertices = numVertices;
        // Инициализация матрицы смежности нулями
        this.adjMatrix = Array.from({ length: numVertices }, () => 
            Array(numVertices).fill(0)
        );
    }
    
    addEdge(u, v, weight = 1) {
        // Добавление ребра между вершинами u и v с весом
        this.adjMatrix[u][v] = weight;
        this.adjMatrix[v][u] = weight; // Для неориентированного графа
    }
    
    display() {
        // Вывод матрицы смежности
        console.log("Матрица смежности:");
        for (let i = 0; i < this.numVertices; i++) {
            console.log(this.adjMatrix[i].join(' '));
        }
    }
}
// Граф с 4 вершинами (0, 1, 2, 3)
// Ребра: 0-1 (вес 2), 0-2 (вес 5), 1-2 (вес 1), 2-3 (вес 3)
const g = new Graph(4);
g.addEdge(0, 1, 2);
g.addEdge(0, 2, 5);
g.addEdge(1, 2, 1);
g.addEdge(2, 3, 3);
// Вывод матрицы смежности
g.display();Матрица смежности реализована как двумерный массив. adjMatrix[i][j] содержит вес ребра между вершинами i и j. Если ребра нет, значение равно 0.
class Graph {
    constructor(numVertices) {
        this.numVertices = numVertices;
        // Инициализация списка смежности
        this.adjList = Array.from({ length: numVertices }, () => ({}));
    }
    
    addEdge(u, v, weight = 1) {
        // Добавление ребра между вершинами u и v с весом
        this.adjList[u][v] = weight;
        this.adjList[v][u] = weight; // Для неориентированного графа
    }
    
    display() {
        // Вывод списка смежности
        console.log("Список смежности:");
        for (let i = 0; i < this.numVertices; i++) {
            const neighbors = Object.entries(this.adjList[i])
                .map(([vertex, weight]) => `(${vertex}, ${weight})`)
                .join(' ');
            console.log(`${i}: ${neighbors}`);
        }
    }
}
// Граф с 4 вершинами (0, 1, 2, 3)
// Ребра: 0-1 (вес 2), 0-2 (вес 5), 1-2 (вес 1), 2-3 (вес 3)
const g = new Graph(4);
g.addEdge(0, 1, 2);
g.addEdge(0, 2, 5);
g.addEdge(1, 2, 1);
g.addEdge(2, 3, 3);
// Вывод списка смежности
g.display();Список смежности реализован как массив объектов, где adjList[i] содержит свойства с именами - смежными вершинами, и значениями - весами соответствующих ребер.
struct Graph {
    num_vertices: usize,
    adj_matrix: Vec<Vec<i32>>,
}
impl Graph {
    fn new(num_vertices: usize) -> Self {
        // Инициализация матрицы смежности нулями
        let adj_matrix = vec![vec![0; num_vertices]; num_vertices];
        Graph {
            num_vertices,
            adj_matrix,
        }
    }
    
    fn add_edge(&mut self, u: usize, v: usize, weight: i32) {
        // Добавление ребра между вершинами u и v с весом
        self.adj_matrix[u][v] = weight;
        self.adj_matrix[v][u] = weight; // Для неориентированного графа
    }
    
    fn display(&self) {
        // Вывод матрицы смежности
        println!("Матрица смежности:");
        for i in 0..self.num_vertices {
            for j in 0..self.num_vertices {
                print!("{} ", self.adj_matrix[i][j]);
            }
            println!();
        }
    }
}
fn main() {
    // Граф с 4 вершинами (0, 1, 2, 3)
    // Ребра: 0-1 (вес 2), 0-2 (вес 5), 1-2 (вес 1), 2-3 (вес 3)
    let mut g = Graph::new(4);
    g.add_edge(0, 1, 2);
    g.add_edge(0, 2, 5);
    g.add_edge(1, 2, 1);
    g.add_edge(2, 3, 3);
    
    // Вывод матрицы смежности
    g.display();
}Матрица смежности реализована как вектор векторов. adj_matrix[i][j] содержит вес ребра между вершинами i и j. Если ребра нет, значение равно 0.
use std::collections::HashMap;
struct Graph {
    num_vertices: usize,
    adj_list: Vec<HashMap<usize, i32>>,
}
impl Graph {
    fn new(num_vertices: usize) -> Self {
        // Инициализация списка смежности
        let mut adj_list = Vec::with_capacity(num_vertices);
        for _ in 0..num_vertices {
            adj_list.push(HashMap::new());
        }
        Graph {
            num_vertices,
            adj_list,
        }
    }
    
    fn add_edge(&mut self, u: usize, v: usize, weight: i32) {
        // Добавление ребра между вершинами u и v с весом
        self.adj_list[u].insert(v, weight);
        self.adj_list[v].insert(u, weight); // Для неориентированного графа
    }
    
    fn display(&self) {
        // Вывод списка смежности
        println!("Список смежности:");
        for (i, neighbors) in self.adj_list.iter().enumerate() {
            print!("{}: ", i);
            for (vertex, weight) in neighbors {
                print!("({}, {}) ", vertex, weight);
            }
            println!();
        }
    }
}
fn main() {
    // Граф с 4 вершинами (0, 1, 2, 3)
    // Ребра: 0-1 (вес 2), 0-2 (вес 5), 1-2 (вес 1), 2-3 (вес 3)
    let mut g = Graph::new(4);
    g.add_edge(0, 1, 2);
    g.add_edge(0, 2, 5);
    g.add_edge(1, 2, 1);
    g.add_edge(2, 3, 3);
    
    // Вывод списка смежности
    g.display();
}Список смежности реализован как вектор HashMap, где adj_list[i] содержит пары ключ-значение: ключ - смежная вершина, значение - вес ребра.
package main
import "fmt"
type Graph struct {
    numVertices int
    adjMatrix   [][]int
}
func NewGraph(numVertices int) *Graph {
    // Инициализация матрицы смежности нулями
    adjMatrix := make([][]int, numVertices)
    for i := range adjMatrix {
        adjMatrix[i] = make([]int, numVertices)
    }
    return &Graph{
        numVertices: numVertices,
        adjMatrix:   adjMatrix,
    }
}
func (g *Graph) AddEdge(u, v, weight int) {
    // Добавление ребра между вершинами u и v с весом
    g.adjMatrix[u][v] = weight
    g.adjMatrix[v][u] = weight // Для неориентированного графа
}
func (g *Graph) Display() {
    // Вывод матрицы смежности
    fmt.Println("Матрица смежности:")
    for i := 0; i < g.numVertices; i++ {
        for j := 0; j < g.numVertices; j++ {
            fmt.Printf("%d ", g.adjMatrix[i][j])
        }
        fmt.Println()
    }
}
func main() {
    // Граф с 4 вершинами (0, 1, 2, 3)
    // Ребра: 0-1 (вес 2), 0-2 (вес 5), 1-2 (вес 1), 2-3 (вес 3)
    g := NewGraph(4)
    g.AddEdge(0, 1, 2)
    g.AddEdge(0, 2, 5)
    g.AddEdge(1, 2, 1)
    g.AddEdge(2, 3, 3)
    
    // Вывод матрицы смежности
    g.Display()
}Матрица смежности реализована как срез срезов. adjMatrix[i][j] содержит вес ребра между вершинами i и j. Если ребра нет, значение равно 0.
package main
import "fmt"
type Graph struct {
    numVertices int
    adjList     []map[int]int
}
func NewGraph(numVertices int) *Graph {
    // Инициализация списка смежности
    adjList := make([]map[int]int, numVertices)
    for i := range adjList {
        adjList[i] = make(map[int]int)
    }
    return &Graph{
        numVertices: numVertices,
        adjList:     adjList,
    }
}
func (g *Graph) AddEdge(u, v, weight int) {
    // Добавление ребра между вершинами u и v с весом
    g.adjList[u][v] = weight
    g.adjList[v][u] = weight // Для неориентированного графа
}
func (g *Graph) Display() {
    // Вывод списка смежности
    fmt.Println("Список смежности:")
    for i := 0; i < g.numVertices; i++ {
        fmt.Printf("%d: ", i)
        for vertex, weight := range g.adjList[i] {
            fmt.Printf("(%d, %d) ", vertex, weight)
        }
        fmt.Println()
    }
}
func main() {
    // Граф с 4 вершинами (0, 1, 2, 3)
    // Ребра: 0-1 (вес 2), 0-2 (вес 5), 1-2 (вес 1), 2-3 (вес 3)
    g := NewGraph(4)
    g.AddEdge(0, 1, 2)
    g.AddEdge(0, 2, 5)
    g.AddEdge(1, 2, 1)
    g.AddEdge(2, 3, 3)
    
    // Вывод списка смежности
    g.Display()
}Список смежности реализован как срез map, где adjList[i] содержит пары ключ-значение: ключ - смежная вершина, значение - вес ребра.
using System;
public class Graph {
    private int numVertices;
    private int[,] adjMatrix;
    
    public Graph(int vertices) {
        this.numVertices = vertices;
        // Инициализация матрицы смежности нулями
        this.adjMatrix = new int[numVertices, numVertices];
    }
    
    public void AddEdge(int u, int v, int weight) {
        // Добавление ребра между вершинами u и v с весом
        adjMatrix[u, v] = weight;
        adjMatrix[v, u] = weight; // Для неориентированного графа
    }
    
    public void Display() {
        // Вывод матрицы смежности
        Console.WriteLine("Матрица смежности:");
        for (int i = 0; i < numVertices; i++) {
            for (int j = 0; j < numVertices; j++) {
                Console.Write(adjMatrix[i, j] + " ");
            }
            Console.WriteLine();
        }
    }
}
public class Program {
    public static void Main() {
        // Граф с 4 вершинами (0, 1, 2, 3)
        // Ребра: 0-1 (вес 2), 0-2 (вес 5), 1-2 (вес 1), 2-3 (вес 3)
        Graph g = new Graph(4);
        g.AddEdge(0, 1, 2);
        g.AddEdge(0, 2, 5);
        g.AddEdge(1, 2, 1);
        g.AddEdge(2, 3, 3);
        
        // Вывод матрицы смежности
        g.Display();
    }
}Матрица смежности реализована как двумерный массив. adjMatrix[i, j] содержит вес ребра между вершинами i и j. Если ребра нет, значение равно 0.
using System;
using System.Collections.Generic;
public class Graph {
    private int numVertices;
    private Dictionary<int, int>[] adjList;
    
    public Graph(int vertices) {
        this.numVertices = vertices;
        // Инициализация списка смежности
        this.adjList = new Dictionary<int, int>[numVertices];
        for (int i = 0; i < numVertices; i++) {
            adjList[i] = new Dictionary<int, int>();
        }
    }
    
    public void AddEdge(int u, int v, int weight) {
        // Добавление ребра между вершинами u и v с весом
        adjList[u][v] = weight;
        adjList[v][u] = weight; // Для неориентированного графа
    }
    
    public void Display() {
        // Вывод списка смежности
        Console.WriteLine("Список смежности:");
        for (int i = 0; i < numVertices; i++) {
            Console.Write($"{i}: ");
            foreach (var pair in adjList[i]) {
                Console.Write($"({pair.Key}, {pair.Value}) ");
            }
            Console.WriteLine();
        }
    }
}
public class Program {
    public static void Main() {
        // Граф с 4 вершинами (0, 1, 2, 3)
        // Ребра: 0-1 (вес 2), 0-2 (вес 5), 1-2 (вес 1), 2-3 (вес 3)
        Graph g = new Graph(4);
        g.AddEdge(0, 1, 2);
        g.AddEdge(0, 2, 5);
        g.AddEdge(1, 2, 1);
        g.AddEdge(2, 3, 3);
        
        // Вывод списка смежности
        g.Display();
    }
}Список смежности реализован как массив Dictionary, где adjList[i] содержит пары ключ-значение: ключ - смежная вершина, значение - вес ребра.
 
 Заключение
# Динамическая типизация
x = 10                    # Целое число
name = "Анна"             # Строка
is_valid = True           # Логическое значение
price = 19.99             # Число с плавающей точкой
# Не требует явного указания типа
# Переменные могут менять тип
x = "теперь строка"       # Динамическое изменение типа
# Множественное присваивание
a, b, c = 1, 2, 3
// Статическая типизация - тип указывается явно
int age = 25;                    // Целое число
String name = "Анна";           // Строка
boolean isActive = true;         // Логическое значение
double price = 19.99;           // Число с плавающей точкой
// final создает константу (неизменяемую переменную)
final double PI = 3.14159;
// Разные целочисленные типы
byte smallNumber = 100;
long bigNumber = 1000000000L;
// Статическая типизация
int count = 10;                  // Целое число
std::string name = "Анна";      // Строка (требует #include <string>)
bool is_valid = true;            // Логическое значение
float price = 19.99f;           // Число с плавающей точкой
// Автовывод типа (C++11 и выше)
auto value = 42;                 // int
auto text = "Hello";            // const char*
// Указатели и ссылки
int number = 100;
int* ptr = &number;             // Указатель
int& ref = number;              // Ссылка
// Динамическая типизация
let age = 25;                   // Число
const name = "Анна";           // Константная строка
var isActive = true;            // Логическое значение (устаревший синтаксис)
// let и const (ES6+)
let counter = 0;                // Можно изменить
const MAX_SIZE = 100;           // Нельзя изменить
// Тип определяется значением
let value = 10;                 // number
value = "теперь строка";        // string - тип изменен
value = true;                   // boolean - тип изменен
// Статическая типизация
int age = 25;                   // Целое число
string name = "Анна";          // Строка
bool isActive = true;           // Логическое значение
double price = 19.99;          // Число с плавающей точкой
// var - вывод типа (статический)
var count = 10;                 // int
var text = "Hello";            // string
// Константы
const double PI = 3.14159;
const int MAX_USERS = 100;
// Nullable типы
int? nullableInt = null;        // Может содержать null
// Статическая типизация с выводом типа
let age = 25;                   // i32 (целое число 32 бита)
let name = "Анна";             // &str (строка)
let is_active = true;           // bool
// По умолчанию переменные неизменяемые
let x = 10;                     // Неизменяемая
let mut y = 20;                 // Изменяемая (ключевое слово mut)
// Аннотации типа (необязательны, когда тип можно вывести)
let price: f64 = 19.99;        // Число с плавающей точкой 64 бита
// Константы
const MAX_POINTS: u32 = 100_000;
// Статическая типизация
var age int = 25               // Явное объявление
var name = "Анна"             // Вывод типа
isActive := true               // Краткое объявление (только внутри функций)
// Краткая форма (только внутри функций)
count := 10                    // int
price := 19.99                 // float64
text := "Hello"               // string
// Множественное объявление
var a, b, c int = 1, 2, 3
x, y, z := 1, "two", true
// Константы
const Pi = 3.14159
const (
    StatusOK = 200
    StatusNotFound = 404
)