图的基础

                                                            

邻接矩阵适合稠密图,邻接表适合稀疏图

 1 // 稠密图 - 邻接矩阵
 2 class DenseGraph {
 3 
 4 private:
 5     int n, m;//顶点和边
 6     bool directed;//有向图还是无向图
 7     vector<vector<bool>> g;//邻接矩阵的表示
 8     //用bool值表示两个顶点之间是否有边
 9 public:
10     DenseGraph(int n, int m) {//构造函数进行初始化
11         this->m = 0;//边数初始为0
12         this->n = n;//顶点数
13         for (int i = 0; i < n; i++) {
14             g.push_back(vector<bool>(n, false));
15         }
16     }
17     ~DenseGraph() {
18 
19     }
20 
21     int V() { return n; }
22     int E() { return m; }
23     void addEdge(int v, int w) {
24         assert(v >= 0 && v < n);
25         assert(w >= 0 && w < n);
26         if (hasEdge(v, w)) return;//判断连个点是否相连
27         g[v][w] = true;
28         if (!directed)
29             g[w][v] = true;
30 
31         m++;
32     }
33     bool hasEdge(int v, int w) {
34         assert(v >= 0 && v < n);
35         assert(w >= 0 && w < n);
36         return g[v][w];
37     }
38 
39     void show() {
40 
41         for (int i = 0; i < n; i++) {
42             for (int j = 0; j < n; j++)
43                 cout << g[i][j] << "\t";
44             cout << endl;
45         }
46     }
47 
48 
49     class adjIterator {//构造一个图的迭代器,用来访问途中某一顶点的连接点
50     private:
51         DenseGraph &G;//
52         int v;//顶点
53         int index;//索引
54     public:
55         adjIterator(DenseGraph &graph, int v) : G(graph) {
56             this->v = v;
57             this->index = -1;
58         }
59 
60         int begin() {
61 
62             index = -1;
63             return next();//将顶点自身
64         }
65 
66         int next() {
67             for (index += 1; index < G.V(); index++)
68                 if (G.g[v][index])
69                     return index;
70             return -1;
71         }
72 
73         bool end() {
74             return index >= G.V();
75         }
76     };
77 
78 };

 

 1 // 稀疏图 - 邻接表
 2 class SparseGraph {
 3 
 4 private:
 5     int n, m;
 6     bool directed;
 7     vector<vector<int>> g;
 8 
 9 public:
10     SparseGraph(int n, bool directed) {
11         this->n = n;
12         this->m = 0;
13         this->directed = directed;
14         for (int i = 0; i < n; i++)
15             g.push_back(vector<int>());
16     }
17 
18     ~SparseGraph() {
19 
20     }
21 
22     int V() { return n; }
23     int E() { return m; }
24 
25     void addEdge(int v, int w) {
26 
27         assert(v >= 0 && v < n);
28         assert(w >= 0 && w < n);
29 
30         g[v].push_back(w);
31         if (v != w && !directed)
32             g[w].push_back(v);
33 
34         m++;
35     }
36 
37     bool hasEdge(int v, int w) {
38 
39         assert(v >= 0 && v < n);
40         assert(w >= 0 && w < n);
41 
42         for (int i = 0; i < g[v].size(); i++)
43             if (g[v][i] == w)
44                 return true;
45         return false;
46     }
47 
48     void show() {
49 
50         for (int i = 0; i < n; i++) {
51             cout << "vertex " << i << ":\t";
52             for (int j = 0; j < g[i].size(); j++)
53                 cout << g[i][j] << "\t";
54             cout << endl;
55         }
56     }
57 
58 
59     class adjIterator {
60     private:
61         SparseGraph &G;
62         int v;
63         int index;
64     public:
65         adjIterator(SparseGraph &graph, int v) : G(graph) {
66             this->v = v;
67             this->index = 0;
68         }
69 
70         int begin() {
71             index = 0;
72             if (G.g[v].size())
73                 return G.g[v][index];
74             return -1;
75         }
76 
77         int next() {
78             index++;
79             if (index < G.g[v].size())
80                 return G.g[v][index];
81             return -1;
82         }
83 
84         bool end() {
85             return index >= G.g[v].size();
86         }
87     };
88 };

读取图的信息的类:

 1 template <typename Graph>
 2 class ReadGraph {
 3 
 4 public:
 5     ReadGraph(Graph &graph, const string &filename) {
 6 
 7         ifstream file(filename);
 8         string line;
 9         int V, E;
10 
11         assert(file.is_open());
12 
13         assert(getline(file, line));
14         stringstream ss(line);
15         ss >> V >> E;
16 
17         assert(V == graph.V());
18 
19         for (int i = 0; i < E; i++) {
20 
21             assert(getline(file, line));
22             stringstream ss(line);
23 
24             int a, b;
25             ss >> a >> b;
26             assert(a >= 0 && a < V);
27             assert(b >= 0 && b < V);
28             graph.addEdge(a, b);
29         }
30     }
31 };

 

遍历临边:

 

深度优先遍历:

 

 

 

深度优先搜索:

 1 template <typename Graph>
 2 class Component {
 3 
 4 private:
 5     Graph &G;
 6     bool *visited;
 7     int ccount;
 8     int *id; 9 10 void dfs(int v) { 11 12 visited[v] = true; 13 id[v] = ccount; 14  typename Graph::adjIterator adj(G, v); 15 for (int i = adj.begin(); !adj.end(); i = adj.next()) { 16 if (!visited[i]) 17  dfs(i); 18  } 19  } 20 21 public: 22 Component(Graph &graph) : G(graph) { 23 24 visited = new bool[G.V()]; 25 id = new int[G.V()]; 26 ccount = 0;//连通域个数 27 for (int i = 0; i < G.V(); i++) { 28 visited[i] = false; 29 id[i] = -1; 30  } 31 32 for (int i = 0; i < G.V(); i++) 33 if (!visited[i]) { 34 dfs(i);//深度优先搜索 35 ccount++; 36  } 37  } 38 39 ~Component() { 40 delete[] visited; 41 delete[] id; 42  } 43 44 int count() { 45 return ccount; 46  } 47 48 bool isConnected(int v, int w) { 49 assert(v >= 0 && v < G.V()); 50 assert(w >= 0 && w < G.V()); 51 return id[v] == id[w]; 52  } 53 };

 路径:

 1 template <typename Graph>
 2 class Path {
 3 
 4 private:
 5     Graph &G;
 6     int s;
 7     bool* visited;
 8     int * from;
 9 
10     void dfs(int v) {
11 
12         visited[v] = true;
13 
14         typename Graph::adjIterator adj(G, v);
15         for (int i = adj.begin(); !adj.end(); i = adj.next()) {
16             if (!visited[i]) {
17                 from[i] = v;
18                 dfs(i);
19             }
20         }
21     }
22 
23 public:
24     Path(Graph &graph, int s) :G(graph) {
25 
26         // 算法初始化
27         assert(s >= 0 && s < G.V());
28 
29         visited = new bool[G.V()];
30         from = new int[G.V()];
31         for (int i = 0; i < G.V(); i++) {
32             visited[i] = false;
33             from[i] = -1;
34         }
35         this->s = s;
36 
37         // 寻路算法
38         dfs(s);
39     }
40 
41     ~Path() {
42 
43         delete[] visited;
44         delete[] from;
45     }
46 
47     bool hasPath(int w) {
48         assert(w >= 0 && w < G.V());
49         return visited[w];
50     }
51 
52     void path(int w, vector<int> &vec) {
53 
54         stack<int> s;
55 
56         int p = w;
57         while (p != -1) {
58             s.push(p);
59             p = from[p];
60         }
61 
62         vec.clear();
63         while (!s.empty()) {
64             vec.push_back(s.top());
65             s.pop();
66         }
67     }
68 
69     void showPath(int w) {
70 
71         vector<int> vec;
72         path(w, vec);
73         for (int i = 0; i < vec.size(); i++) {
74             cout << vec[i];
75             if (i == vec.size() - 1)
76                 cout << endl;
77             else
78                 cout << " -> ";
79         }
80     }
81 };

广度优先遍历:使用队列实现。可以求出最短路径

 

 

  1 template <typename Graph>
  2 class ShortestPath {
  3 
  4 private:
  5     Graph &G;
  6     int s;
  7     bool *visited;
  8     int *from;
  9     int *ord;
 10 
 11 public:
 12     ShortestPath(Graph &graph, int s) :G(graph) {
 13 
 14         // 算法初始化
 15         assert(s >= 0 && s < graph.V());
 16 
 17         visited = new bool[graph.V()];
 18         from = new int[graph.V()];
 19         ord = new int[graph.V()];
 20         for (int i = 0; i < graph.V(); i++) {
 21             visited[i] = false;
 22             from[i] = -1;
 23             ord[i] = -1;
 24         }
 25         this->s = s;
 26 
 27         queue<int> q;
 28 
 29         // 无向图最短路径算法
 30         q.push(s);
 31         visited[s] = true;
 32         ord[s] = 0;
 33         while (!q.empty()) {
 34 
 35             int v = q.front();
 36             q.pop();
 37 
 38             typename Graph::adjIterator adj(G, v);
 39             for (int i = adj.begin(); !adj.end(); i = adj.next())
 40                 if (!visited[i]) {
 41                     q.push(i);
 42                     visited[i] = true;
 43                     from[i] = v;
 44                     ord[i] = ord[v] + 1;
 45                 }
 46         }
 47 
 48     }
 49 
 50     ~ShortestPath() {
 51 
 52         delete[] visited;
 53         delete[] from;
 54         delete[] ord;
 55     }
 56 
 57     bool hasPath(int w) {
 58         assert(w >= 0 && w < G.V());
 59         return visited[w];
 60     }
 61 
 62     void path(int w, vector<int> &vec) {
 63 
 64         assert(w >= 0 && w < G.V());
 65 
 66         stack<int> s;
 67 
 68         int p = w;
 69         while (p != -1) {
 70             s.push(p);
 71             p = from[p];
 72         }
 73 
 74         vec.clear();
 75         while (!s.empty()) {
 76             vec.push_back(s.top());
 77             s.pop();
 78         }
 79     }
 80 
 81     void showPath(int w) {
 82 
 83         assert(w >= 0 && w < G.V());
 84 
 85         vector<int> vec;
 86         path(w, vec);
 87         for (int i = 0; i < vec.size(); i++) {
 88             cout << vec[i];
 89             if (i == vec.size() - 1)
 90                 cout << endl;
 91             else
 92                 cout << " -> ";
 93         }
 94     }
 95 
 96     int length(int w) {
 97         assert(w >= 0 && w < G.V());
 98         return ord[w];
 99     }
100 };

 

转载于:https://www.cnblogs.com/bingzzzZZZ/p/8466252.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值