C++——图

图是由节点(顶点)和连接节点的边组成的一种非线性数据结构。它用于表示不同对象之间的关系或网络结构。图可以用于建模和解决许多现实世界中的问题,例如社交网络分析、路线规划、图像处理等。

在图中,节点表示实体或对象,而边表示节点之间的关系。边可以是有向的(具有方向)或无向的(没有方向),并可以具有权重或标签来表示边的属性或距离。

有几种常见的图数据结构,包括:

  1. 邻接矩阵(Adjacency Matrix):邻接矩阵是一个二维数组,用于表示图中节点之间的连接关系。矩阵的行和列分别代表图中的节点,矩阵元素表示节点之间的边或连接。如果节点 i 和节点 j 之间有边存在,则邻接矩阵的 (i, j) 位置上的值为 1 或权重值,否则为 0 或表示不存在的标记。邻接矩阵适用于稠密图,但对于大型稀疏图来说会占用较多的内存空间
  2. 邻接列表(Adjacency List):邻接列表使用链表或数组的列表来表示节点及其相邻节点的关系。每个节点都有一个列表,列出与其直接相连的节点。邻接列表适用于稀疏图,因为它只需要存储节点的相邻节点信息,可以节省内存空间。
  3. 关联矩阵(Incidence Matrix):关联矩阵使用二维矩阵表示节点和边之间的关系。矩阵的行代表节点,列代表边,矩阵元素表示节点和边之间的关联关系。如果节点 i 是边 j 的起点,则矩阵的 (i, j) 位置上的值为 1 或权重值,如果节点 i 是边 j 的终点,则该位置上的值为 -1。关联矩阵适用于有向图以及边有多个属性的图。
  4. 哈希表或字典(Hash Table or Dictionary):链表表示法是一种灵活的图数据结构,使用节点和边的链表来表示图。每个节点包含节点的信息以及指向其相邻节点的指针。边也可以作为链表节点的一部分存储。链表表示法适用于动态图或需要频繁地添加和删除节点和边的情况。

图的邻接矩阵

在C++中,可以使用二维数组来表示图的邻接矩阵。以下是一个简单的示例代码,展示了如何使用邻接矩阵表示有向图:

#include <iostream>
#include <vector>

// 定义图类
class Graph {
private:
    int numVertices;  // 图中的节点数
    std::vector<std::vector<int>> adjacencyMatrix;  // 邻接矩阵

public:
    // 构造函数
    Graph(int numVertices) : numVertices(numVertices) {
        // 初始化邻接矩阵为全零
        adjacencyMatrix.resize(numVertices, std::vector<int>(numVertices, 0));
    }

    // 添加边
    void addEdge(int src, int dest) {
        // 在邻接矩阵中设置边的连接关系
        adjacencyMatrix[src][dest] = 1;
    }

    // 打印邻接矩阵
    void printAdjacencyMatrix() {
        for (int i = 0; i < numVertices; ++i) {
            for (int j = 0; j < numVertices; ++j) {
                std::cout << adjacencyMatrix[i][j] << " ";
            }
            std::cout << std::endl;
        }
    }
};

int main() {
    // 创建一个包含5个节点的有向图
    Graph graph(5);

    // 添加边
    graph.addEdge(0, 1);
    graph.addEdge(0, 4);
    graph.addEdge(1, 2);
    graph.addEdge(1, 3);
    graph.addEdge(2, 3);
    graph.addEdge(3, 4);

    // 打印邻接矩阵
    graph.printAdjacencyMatrix();

    return 0;
}

上述代码中,首先定义了一个Graph类,其中包含私有成员变量numVertices表示节点数,以及adjacencyMatrix用于存储邻接矩阵。构造函数初始化邻接矩阵为全零。

通过addEdge函数可以向图中添加边,该函数会在邻接矩阵中设置对应位置的值为 1 来表示节点之间的连接关系。

最后,通过printAdjacencyMatrix函数可以打印邻接矩阵的内容。运行结果为:

0 1 0 0 1 
0 0 1 1 0 
0 0 0 1 0 
0 0 0 0 1 
0 0 0 0 0 

请注意,上述代码只展示了有向图的邻接矩阵表示方法。如果需要表示无向图,可以将邻接矩阵设置为对称矩阵,即在设置边连接关系时同时设置两个对称位置的值为 1。

图的邻接表

在C++中,可以使用链表来实现图的邻接表。每个节点通过一个链表存储其相邻节点的信息。以下是一个简单的示例代码,展示了如何使用链表实现图的邻接表表示:

#include <iostream>

// 定义图节点的结构
struct Node {
    int dest;       // 相邻节点的目标
    Node* next;     // 指向下一个相邻节点的指针
};

// 定义图类
class Graph {
private:
    int numVertices;    // 图中的节点数
    Node** adjacencyList;   // 邻接表

public:
    // 构造函数
    Graph(int numVertices) : numVertices(numVertices) {
        adjacencyList = new Node*[numVertices]();

        // 初始化邻接表为空
        for (int i = 0; i < numVertices; ++i) {
            adjacencyList[i] = nullptr;
        }
    }

    // 添加边
    void addEdge(int src, int dest) {
        // 创建新的节点
        Node* newNode = new Node;
        newNode->dest = dest;
        newNode->next = nullptr;

        // 将新节点插入到src节点的邻接列表头部
        newNode->next = adjacencyList[src];
        adjacencyList[src] = newNode;

        // 对于无向图,还需插入反向边
        newNode = new Node;
        newNode->dest = src;
        newNode->next = nullptr;
        newNode->next = adjacencyList[dest];
        adjacencyList[dest] = newNode;
    }

    // 打印邻接表
    void printAdjacencyList() {
        for (int i = 0; i < numVertices; ++i) {
            Node* currentNode = adjacencyList[i];
            std::cout << "顶点 " << i << " 的邻接列表: ";
            while (currentNode != nullptr) {
                std::cout << currentNode->dest << " ";
                currentNode = currentNode->next;
            }
            std::cout << std::endl;
        }
    }

    // 析构函数,释放内存
    ~Graph() {
        for (int i = 0; i < numVertices; ++i) {
            Node* currentNode = adjacencyList[i];
            while (currentNode != nullptr) {
                Node* nextNode = currentNode->next;
                delete currentNode;
                currentNode = nextNode;
            }
        }
        delete[] adjacencyList;
    }
};

int main() {
    // 创建一个包含5个节点的无向图
    Graph graph(5);

    // 添加边
    graph.addEdge(0, 1);
    graph.addEdge(0, 4);
    graph.addEdge(1, 2);
    graph.addEdge(1, 3);
    graph.addEdge(2, 3);
    graph.addEdge(3, 4);

    // 打印邻接表
    graph.printAdjacencyList();

    return 0;
}

以下是使用邻接表表示图的示例代码:

#include <iostream>
#include <vector>

class Graph {
private:
    int numVertices;                // 图中的节点数
    std::vector<std::vector<int>> adjList;   // 邻接表

public:
    // 构造函数
    Graph(int numVertices) : numVertices(numVertices) {
        adjList.resize(numVertices);
    }

    // 添加边
    void addEdge(int src, int dest) {
        adjList[src].push_back(dest);
        adjList[dest].push_back(src);   // 对于无向图,需要添加反向的边
    }

    // 打印邻接表
    void printGraph() {
        for (int i = 0; i < numVertices; ++i) {
            std::cout << "节点 " << i << " 的相邻节点:";
            for (int neighbor : adjList[i]) {
                std::cout << neighbor << " ";
            }
            std::cout << std::endl;
        }
    }
};

int main() {
    // 创建一个包含5个节点的图
    Graph graph(5);

    // 添加边
    graph.addEdge(0, 1);
    graph.addEdge(0, 2);
    graph.addEdge(1, 3);
    graph.addEdge(2, 3);
    graph.addEdge(2, 4);
    graph.addEdge(3, 4);

    // 打印邻接表
    graph.printGraph();

    return 0;
}

在上述代码中,我们定义了一个Graph类来表示图。使用邻接表作为内部数据结构,使用std::vector<std::vector<int>> adjList来存储图的邻接表,其中每个向量表示节点的相邻节点列表。

addEdge函数用于向图中添加边,它将目标节点添加到源节点的相邻节点列表中,并对于无向图,还需要添加反向的边。

printGraph函数用于打印图的邻接表。它遍历每个节点,并输出其相邻节点列表。

在示例代码中,我们创建了一个包含5个节点的图,并添加了一些边。然后,通过调用printGraph函数,打印图的邻接表。

这种邻接表表示法对于稀疏图(边相对较少)非常高效,可以快速查找每个节点的相邻节点,并节省存储空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值