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;
}