图 模板


title: 图
author: 龙威旭
date: 2024-06-19 21:25:02
tags: 英雄数据结构
categories: 数据结构

以下内容来自英雄哥的数据结构c++课程

邻接矩阵

概念

由于图是由顶点和边(或弧)两部分组成的。顶点可以用一个一维的顺序表来存储,但是边 (或弧)由于是顶点与顶点之问的关系,一维搞不定,所以可以考虑用一个二维的顺序表来存储, 而二维的顺序表就是一个矩阵。

对于一个有n个顶点的图 G,邻接矩阵是一个n x n的方阵(方阵就是行列数相等的矩阵)。对于邻接矩阵而言,不需要去考虑是有向的还是无向的,统一都可以理解成有向的,因为有向图可以兼容无向图,对于无向图而言,只不过这个矩阵是按照主对角线对称的,因为 A到B有边,则必然B到A有边。



邻接矩阵

#include<iostream>
using namespace std;

// 定义一个常量用于表示无边的情况,这里使用-1表示
#define inf -1

// 图类定义
class Graph{
private:
    int vertices;   // 顶点数量
    int **edges;    // 邻接矩阵,存储边的权重

public:
    Graph(int vertices);  // 构造函数
    ~Graph();             // 析构函数
    void addEdge(int u, int v, int w);  // 添加边
    void printGraph();    // 打印图的邻接矩阵
};

// 构造函数的实现
Graph::Graph(int vertices){
    this->vertices = vertices;  // 初始化顶点数量
    edges = new int* [vertices];  // 动态分配二维数组
    for(int i = 0; i < vertices; ++i){
        edges[i] = new int[vertices];  // 为每个顶点分配边的数组
        for(int j = 0; j < vertices; ++j){
            edges[i][j] = inf;  // 初始化所有边为inf(无边)
        }
    }
}

// 析构函数的实现
Graph::~Graph(){
    for(int i = 0; i < vertices; ++i){
        delete[] edges[i];  // 释放每个顶点的边数组
    }
    delete[] edges;  // 释放顶点数组
}

// 添加边的方法实现
void Graph::addEdge(int u, int v, int w){
    edges[u][v] = w;  // 在邻接矩阵中设置边的权重
}

// 打印邻接矩阵的方法实现
void Graph::printGraph(){
    for(int i = 0; i < vertices; ++i){
        for(int j = 0; j < vertices; ++j){
            cout << edges[i][j] << "\t";  // 打印每个边的权重,用制表符分隔
        }
        cout << endl;  // 每行打印完毕后换行
    }
}

// 主函数
int main(){
    int vertices = 5;  // 定义图的顶点数量
    Graph graph(vertices);  // 创建图对象

    // 添加边,参数为起点、终点和权重
    graph.addEdge(0, 1, 1);
    graph.addEdge(0, 2, 3);
    graph.addEdge(1, 2, 2);
    graph.addEdge(2, 3, 7);
    graph.addEdge(3, 4, 9);
    graph.addEdge(4, 0, 4);
    graph.addEdge(4, 2, 5);

    // 打印图的邻接矩阵
    graph.printGraph();
    return 0;
}

邻接表

#include <iostream>
using namespace std;

// 图类定义
class Graph{
private:
    // 边节点结构体
    struct EdgeNode{
        int vertex;       // 终点
        int weight;       // 权重
        EdgeNode* next;   // 指向下一条边的指针
    };
    
    // 顶点节点结构体
    struct VertexNode{
        int vertex;       // 顶点编号
        EdgeNode* firstEdge; // 指向第一条边的指针
    };

    int vertices;         // 顶点数量
    VertexNode* nodes;    // 顶点数组

public:
    Graph(int vertices);  // 构造函数
    ~Graph();             // 析构函数
    void addEdge(int u, int v, int w);  // 添加边的方法
    void printGraph();    // 打印图的方法
};

// 构造函数的实现
Graph::Graph(int vertices){
    this->vertices = vertices;
    this->nodes = new VertexNode[vertices];
    for(int i = 0; i < vertices; ++i){
        nodes[i].vertex = i;
        nodes[i].firstEdge = nullptr;
    }
}

// 析构函数的实现
Graph::~Graph(){
    for(int i = 0; i < vertices; ++i){
        EdgeNode* curr = nodes[i].firstEdge;
        while(curr){
            EdgeNode* temp = curr;
            curr = curr->next;
            delete temp;
        }
    }
    delete[] nodes;
}

// 添加边的方法实现
void Graph::addEdge(int u, int v, int w){
    EdgeNode* newNode = new EdgeNode;
    newNode->vertex = v;
    newNode->weight = w;
    newNode->next = nodes[u].firstEdge;
    nodes[u].firstEdge = newNode;
}

// 打印图的方法实现
void Graph::printGraph(){
    for(int i = 0; i < vertices; ++i){
        EdgeNode* curr = nodes[i].firstEdge;
        cout << "Vertex " << i << ": ";
        while(curr){
            cout << curr->vertex << "(" << curr->weight << ") ";
            curr = curr->next;
        }
        cout << endl;
    }
}

// 主函数
int main(){
    Graph graph(5);
    graph.addEdge(0, 1, 4); 
    graph.addEdge(0, 2, 2); 
    graph.addEdge(1, 2, 3); 
    graph.addEdge(2, 3, 4); 
    graph.addEdge(3, 4, 2);

    graph.printGraph();  // 调用方法时需要括号
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Long韵韵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值