c++图论详解

目录

引言

一、图的基本定义 

1.图的组成部分

2.图的类型 

3.图的表示方式 

二、图的遍历算法

1.深度优先搜索(Depth First Search,DFS)

2.广度优先搜索(Breadth First Search,BFS) 

三、最短路径算法

1.迪杰斯特拉(Dijkstra)算法

四、图的应用举例 

1.社交网络分析

2.最短路径规划 

3.网络流量优化 

结论

参考资料

相关网站推荐


引言

图论是数学的一个分支,研究图形结构的性质和算法。在计算机科学领域,图论被广泛应用于解决各种实际问题,如网络通信、社交网络分析、路径规划等。本文将深入探讨图论相关概念和算法,并通过代码实例展示它们的具体应用。


一、图的基本定义 

1.图的组成部分

  • 顶点(Vertex):图中的节点或元素。
  • 边(Edge):连接两个顶点的线段,表示顶点之间的关系。

2.图的类型 

  • 有向图(Directed Graph):顶点之间的边有方向。
  • 无向图(Undirected Graph):顶点之间的边没有方向。

3.图的表示方式 

  • 邻接矩阵(Adjacency Matrix):使用二维数组表示顶点之间的关系。
  • 邻接表(Adjacency List):使用链表或数组表示顶点及其相邻顶点的关系。

二、图的遍历算法

1.深度优先搜索(Depth First Search,DFS)

  • 基本思想:从某个顶点开始,沿着一条路径尽可能深入,直到无法前进为止,然后回溯到前一个顶点,再选择另一条路径继续深入。
  • DFS算法可以用递归或栈来实现。
#include <iostream>
#include <vector>

using namespace std;

class Graph {
private:
    vector<vector<int>> adjacencyList;
    vector<bool> visited;

public:
    Graph(int n) {
        adjacencyList.resize(n);
        visited.resize(n, false);
    }

    void addEdge(int u, int v) {
        adjacencyList[u].push_back(v);
        adjacencyList[v].push_back(u);
    }

    void DFS(int vertex) {
        visited[vertex] = true;
        cout << vertex << " ";

        for (int i = 0; i < adjacencyList[vertex].size(); i++) {
            int neighbor = adjacencyList[vertex][i];
            if (!visited[neighbor]) {
                DFS(neighbor);
            }
        }
    }
};

int main() {
    Graph graph(6);

    graph.addEdge(0, 1);
    graph.addEdge(0, 2);
    graph.addEdge(1, 3);
    graph.addEdge(1, 4);
    graph.addEdge(2, 5);

    cout << "DFS traversal: ";
    graph.DFS(0);

    return 0;
}

2.广度优先搜索(Breadth First Search,BFS) 

  • 基本思想:从某个顶点开始,先访问其所有邻居顶点,然后按照相邻顶点被添加的顺序逐个访问它们的邻居顶点。
  • BFS算法使用队列来实现。
#include <iostream>
#include <vector>
#include <queue>

using namespace std;

class Graph {
private:
    vector<vector<int>> adjacencyList;
    vector<bool> visited;

public:
    Graph(int n) {
        adjacencyList.resize(n);
        visited.resize(n, false);
    }

    void addEdge(int u, int v) {
        adjacencyList[u].push_back(v);
        adjacencyList[v].push_back(u);
    }

    void BFS(int vertex) {
        queue<int> q;
        visited[vertex] = true;
        q.push(vertex);

        while (!q.empty()) {
            int current = q.front();
            q.pop();
            cout << current << " ";

            for (int i = 0; i < adjacencyList[current].size(); i++) {
                int neighbor = adjacencyList[current][i];
                if (!visited[neighbor]) {
                    visited[neighbor] = true;
                    q.push(neighbor);
                }
            }
        }
    }
};

int main() {
    Graph graph(6);

    graph.addEdge(0, 1);
    graph.addEdge(0, 2);
    graph.addEdge(1, 3);
    graph.addEdge(1, 4);
    graph.addEdge(2, 5);

    cout << "BFS traversal: ";
    graph.BFS(0);

    return 0;
}

三、最短路径算法

1.迪杰斯特拉(Dijkstra)算法

  • 基本思想:通过逐步确定从起点到其他顶点的最短路径的方式,逐渐得到最终结果。
  • 迪杰斯特拉算法使用优先队列或堆来实现。
#include <iostream>
#include <vector>
#include <queue>

using namespace std;

#define INF 99999

class Graph {
private:
    int numVertices;
    vector<vector<pair<int, int>>> adjacencyList; // 存储邻接顶点及对应的权重

public:
    Graph(int n) : numVertices(n) {
        adjacencyList.resize(n);
    }

    void addEdge(int u, int v, int weight) {
        adjacencyList[u].push_back({v, weight});
        adjacencyList[v].push_back({u, weight});
    }

    void Dijkstra(int startVertex) {
        vector<int> distance(numVertices, INF);
        vector<bool> visited(numVertices, false);
        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;

        distance[startVertex] = 0;
        pq.push({0, startVertex});

        while (!pq.empty()) {
            int current = pq.top().second;
            pq.pop();

            if (visited[current]) {
                continue;
            }

            visited[current] = true;

            for (pair<int, int> neighbor : adjacencyList[current]) {
                int vertex = neighbor.first;
                int weight = neighbor.second;
                int totalDistance = distance[current] + weight;

                if (totalDistance < distance[vertex]) {
                    distance[vertex] = totalDistance;
                    pq.push({distance[vertex], vertex});
                }
            }
        }

        cout << "Shortest distances from vertex " << startVertex << ":\n";
        for (int i = 0; i < numVertices; i++) {
            cout << "Vertex " << i << ": " << distance[i] << endl;
        }
    }
};

int main() {
    Graph graph(6);

    graph.addEdge(0, 1, 2);
    graph.addEdge(0, 2, 4);
    graph.addEdge(1, 3, 1);
    graph.addEdge(1, 4, 7);
    graph.addEdge(2, 5, 3);

    graph.Dijkstra(0);

    return 0;
}

四、图的应用举例 

1.社交网络分析

  • 利用图论算法可以分析社交网络中的用户关系、社区发现和信息传播等问题。
  • 可以使用图的遍历算法查找特定用户之间的关系路径,实现好友推荐和社交影响力评估等功能。

2.最短路径规划 

  • ​​​​​在地图导航或物流路径规划中,使用图论算法可以找到最短路径,节省时间和成本。
  • 可以使用迪杰斯特拉算法或其他最短路径算法来确定两个地点之间的最佳路线。

3.网络流量优化 

  • 通过建模为图论问题,可以对网络流量进行优化,如路由器链路优化、最大流最小割问题等。

结论

图论在计算机科学中扮演着重要的角色,广泛应用于各种实际问题的解决。本文详细介绍了图的基本定义、遍历算法、最短路径算法以及应用举例,并提供了相应的代码示例。希望读者通过学习图论,能够在实际的计算机科学问题中灵活应用它们,提高软件系统的效率和性能。


参考资料

  • Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest and Clifford Stein. Introduction to Algorithms (Third Edition). MIT Press, 2009.
  • Sedgewick, Robert, and Kevin Wayne. Algorithms. Addison-Wesley Professional, 2011.

相关网站推荐

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C++中的vector是一个动态数组,可以在运行时动态地增加或减少其大小。它提供了许多方便的方法来操作数组,例如在末尾添加元素、在任意位置插入元素、删除元素等等。下面是一些常用的vector操作: 1. 创建vector对象:可以使用默认构造函数创建一个空的vector对象,也可以使用带有初始值的构造函数创建一个包含初始值的vector对象。 ```c++ // 创建一个空的vector对象 std::vector<int> v1; // 创建一个包含初始值的vector对象 std::vector<int> v2 = {1, 2, 3}; ``` 2. 访问vector元素:可以使用下标运算符[]或at()方法来访问vector中的元素。 ```c++ std::vector<int> v = {1, 2, 3}; // 使用下标运算符[]访问元素 int x = v[0]; // x = 1 // 使用at()方法访问元素 int y = v.at(1); // y = 2 ``` 3. 在末尾添加元素:可以使用push_back()方法在vector的末尾添加一个元素。 ```c++ std::vector<int> v = {1, 2, 3}; // 在末尾添加一个元素 v.push_back(4); // v = {1,2, 3, 4} ``` 4. 在任意位置插入元素:可以使用insert()方法在vector的任意位置插入一个元素。 ```c++ std::vector<int> v = {1, 2, 3}; // 在第二个位置插入一个元素 v.insert(v.begin() + 1, 4); // v = {1, 4, 2, 3} ``` 5. 删除元素:可以使用erase()方法删除vector中的一个或多个元素。 ```c++ std::vector<int> v = {1, 2, 3}; // 删除第二个元素 v.erase(v.begin() + 1); // v = {1, 3} // 删除第二个到第三个元素 v.erase(v.begin() + 1, v.begin() + 3); // v = {1} ``` 6. 获取vector大小:可以使用size()方法获取vector中元素的数量。 ```c++ std::vector<int> v = {1, 2, 3}; // 获取vector大小 int size = v.size(); // size = 3 ``` 7. 清空vector:可以使用clear()方法清空vector中的所有元素。 ```c++ std::vector<int> v = {1, 2, 3}; // 清空vector v.clear(); // v = {} ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

浪子小院

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

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

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

打赏作者

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

抵扣说明:

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

余额充值