diff --git a/Graph/adjacencyMatrix/adjacencyMatrix.h b/Graph/adjacencyMatrix/adjacencyMatrix.h new file mode 100644 index 0000000..5cd9cea --- /dev/null +++ b/Graph/adjacencyMatrix/adjacencyMatrix.h @@ -0,0 +1,157 @@ +/* +这里我们规定顶点从0开始,如果从1开始,则代码需要通过(_v - 1)的方式修改进入matrix的方式 +*/ +#pragma once +#include +#include "graph.h" +#include "vertexIterator.h" +#include +#include +#include +template +class adjacencyMatrix : public Graph { +private: + int v; + int e; + std::vector> matrix; + std::vector reach; + static constexpr T INF = std::numeric_limits::infinity(); // 非常重要:-| 无边时的值 + //如果是static const类内声明,要类外定义 + + //关注:迭代器iterator在类里面初始化,嵌套类 + class VertexIteratorImpl : public vertexIterator { + private: + const std::vector& neighbors; // 当前节点的邻居行 + int current; // 当前邻居索引 + int n; // 矩阵维度 + const T INF; // 无边标记 + + public: + VertexIteratorImpl(const std::vector& row, int size, T inf) + : neighbors(row), current(0), n(size), INF(inf) { + } + + int next() override { + while (current < n && neighbors[current] == INF) { + ++current; + } + if (current < n) { + return current++; + } + return -1; // 没有更多邻居 + } + + bool hasNext() const override { + int temp = current; + while (temp < n && neighbors[temp] == INF) { + ++temp; + } + return temp < n; + } + }; + +public: + adjacencyMatrix(int _v): v(_v), e(0) { + //很重要,先把所有边置零 + matrix.assign(_v, std::vector(_v, INF)); + reach.assign(_v, false); + } + ~adjacencyMatrix() override {} + bool validateV(int _v) const { + return _v >= 0 && _v < v; + } + int numberOfVertices() const override { return v; } + int numberOfEdges() const override { return e; } + bool existsEdge(int _a, int _b) const override { + //有向图,特指a->b + if (!validateV(_a) || !validateV(_b)) return false; + return matrix[_a][_b] != INF; + } + void insertEdge(edge* _e) override { + if (!_e) return; + if (!validateV(_e->from) || !validateV(_e->to)) return; + matrix[_e->from][_e->to] = _e->weight; + e++; + } + void eraseEdge(int _a, int _b){ + if (!validateV(_a) || !validateV(_b)) return; + matrix[_a][_b] = INF; + e--; + } + //关注环 + int degree(int _v) const override { + return inDegree(_v) + outDegree(_v); + } + int inDegree(int _v) const override { + int js = 0; + for (int i = 0;i < v; i++) { + if (matrix[i][_v] != INF) js++; + } + return js; + } + int outDegree(int _v) const { + int js = 0; + for (auto x : matrix[_v]) { + if (x != INF) js++; + } + return js; + } + // 返回节点u的邻居迭代器 + vertexIterator* iterator(int _v) override { + validateV(_v); + return new VertexIteratorImpl(matrix[_v], v, INF); + } + // 是否为有向图 + bool directed() const override { + return true; // 有向图 + } + + // 是否为加权图 + bool weighted() const override { + return true; // 加权图 + } + + void bfs(int _v); + void dfs(int _v); +}; + +template +inline void adjacencyMatrix::bfs(int _v) +{ + std::deque arr; + arr.push_back(_v); + std::vector visited; + visited.assign(v, false); + visited[_v] = true; + + while (!arr.empty()) { + int u = arr.front(); + std::cout << u << " "; + arr.pop_front(); + + for (int i = 0; i < v; i++) { + if (matrix[u][i] != INF && !visited[i]) { + arr.push_back(i); + visited[i] = true; + } + } + } + std::cout << std::endl; +} + +template +inline void adjacencyMatrix::dfs(int _v) +{ + if (!validateV(_v)) return; + if (reach.at(_v) == true) return; + reach.at(_v) = true; + + std::cout << _v << " "; + for (int i = 0; i < v; i++) { + if (matrix[_v][i] != INF && reach.at(i) == false) { + dfs(i); + } + } + //后序输出std::cout << _v << " "; +} + diff --git a/Graph/adjacencyMatrix/graph.h b/Graph/adjacencyMatrix/graph.h new file mode 100644 index 0000000..b74af5d --- /dev/null +++ b/Graph/adjacencyMatrix/graph.h @@ -0,0 +1,27 @@ +#pragma once +#include "vertexIterator.h" +template +struct edge { + int from, to; + T weight; + + edge(int _from, int _to, T _weight) : from(_from), to(_to), weight(_weight) {} +}; +template +class Graph { +public: + virtual ~Graph() {} + + //ADT Methods + virtual int numberOfVertices() const = 0; + virtual int numberOfEdges() const = 0; + virtual bool existsEdge(int, int) const = 0; + virtual void insertEdge(edge*) = 0; + virtual int degree(int) const = 0; + virtual int inDegree(int) const = 0; + + //Other Methods + virtual bool directed() const = 0; //有向图 + virtual bool weighted() const = 0; //有向加权图 + virtual vertexIterator* iterator(int) = 0; //迭代器 +}; \ No newline at end of file diff --git a/Graph/adjacencyMatrix/main.cpp b/Graph/adjacencyMatrix/main.cpp new file mode 100644 index 0000000..ba67d97 --- /dev/null +++ b/Graph/adjacencyMatrix/main.cpp @@ -0,0 +1,14 @@ +#include "adjacencyMatrix.h" +using namespace std; +int main() { + adjacencyMatrix g(11); + edge e1(1, 2, 0.5), e2(1, 3, 0.6), e3(1, 4, 0.7) , e4(1, 5, 0.8), e5(3, 10, 0.9); + edge e6(10, 7, 0.5), e7(2, 5, 0.6), e8(5, 8, 0.7); + g.insertEdge(&e1);g.insertEdge(&e2);g.insertEdge(&e3);g.insertEdge(&e4);g.insertEdge(&e5);g.insertEdge(&e6);g.insertEdge(&e7);g.insertEdge(&e8); + cout << g.degree(1) << endl; + cout << g.inDegree(5) << endl; + cout << g.outDegree(8) << endl; + g.bfs(1); + g.dfs(1); + return 0; +} \ No newline at end of file diff --git a/Graph/adjacencyMatrix/vertexIterator.h b/Graph/adjacencyMatrix/vertexIterator.h new file mode 100644 index 0000000..204fa7b --- /dev/null +++ b/Graph/adjacencyMatrix/vertexIterator.h @@ -0,0 +1,8 @@ +#pragma once +template +class vertexIterator { +public: + virtual ~vertexIterator() {} + virtual int next() = 0; + virtual bool hasNext() const = 0; +}; \ No newline at end of file