AdjacencyMatrix

This commit is contained in:
e2hang
2025-08-28 13:45:08 +08:00
parent 357d37b72a
commit b97f348a51
4 changed files with 206 additions and 0 deletions

View File

@@ -0,0 +1,157 @@
/*
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǹ涨<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫͨ<EFBFBD><EFBFBD>(_v - 1)<29>ķ<EFBFBD>ʽ<EFBFBD>޸Ľ<DEB8><C4BD><EFBFBD>matrix<69>ķ<EFBFBD>ʽ
*/
#pragma once
#include <iostream>
#include "graph.h"
#include "vertexIterator.h"
#include <deque>
#include <limits>
#include <vector>
template <class T>
class adjacencyMatrix : public Graph<T> {
private:
int v;
int e;
std::vector<std::vector<T>> matrix;
std::vector<bool> reach;
static constexpr T INF = std::numeric_limits<T>::infinity(); // <20>dz<EFBFBD><C7B3><EFBFBD>Ҫ:-| <20>ޱ<EFBFBD>ʱ<EFBFBD><CAB1>ֵ
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>static const<73><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><E2B6A8>
//<2F><>ע<EFBFBD><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>iterator<6F><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>Ƕ<EFBFBD><C7B6><EFBFBD><EFBFBD>
class VertexIteratorImpl : public vertexIterator<T> {
private:
const std::vector<T>& neighbors; // <20><>ǰ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD>ھ<EFBFBD><DABE><EFBFBD>
int current; // <20><>ǰ<EFBFBD>ھ<EFBFBD><DABE><EFBFBD><EFBFBD><EFBFBD>
int n; // <20><><EFBFBD><EFBFBD>ά<EFBFBD><CEAC>
const T INF; // <20>ޱ߱<DEB1><DFB1><EFBFBD>
public:
VertexIteratorImpl(const std::vector<T>& 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; // û<>и<EFBFBD><D0B8><EFBFBD><EFBFBD>ھ<EFBFBD>
}
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) {
//<2F><><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>Ȱ<EFBFBD><C8B0><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD>
matrix.assign(_v, std::vector<T>(_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 {
//<2F><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD>ָa->b
if (!validateV(_a) || !validateV(_b)) return false;
return matrix[_a][_b] != INF;
}
void insertEdge(edge<T>* _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--;
}
//<2F><>ע<EFBFBD><D7A2>
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;
}
// <20><><EFBFBD>ؽڵ<D8BD>u<EFBFBD><75><EFBFBD>ھӵ<DABE><D3B5><EFBFBD><EFBFBD><EFBFBD>
vertexIterator<T>* iterator(int _v) override {
validateV(_v);
return new VertexIteratorImpl(matrix[_v], v, INF);
}
// <20>Ƿ<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>ͼ
bool directed() const override {
return true; // <20><><EFBFBD><EFBFBD>ͼ
}
// <20>Ƿ<EFBFBD>Ϊ<EFBFBD><CEAA>Ȩͼ
bool weighted() const override {
return true; // <20><>Ȩͼ
}
void bfs(int _v);
void dfs(int _v);
};
template<class T>
inline void adjacencyMatrix<T>::bfs(int _v)
{
std::deque<int> arr;
arr.push_back(_v);
std::vector<bool> 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<class T>
inline void adjacencyMatrix<T>::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);
}
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>std::cout << _v << " ";
}

View File

@@ -0,0 +1,27 @@
#pragma once
#include "vertexIterator.h"
template <class T>
struct edge {
int from, to;
T weight;
edge(int _from, int _to, T _weight) : from(_from), to(_to), weight(_weight) {}
};
template <class T>
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<T>*) = 0;
virtual int degree(int) const = 0;
virtual int inDegree(int) const = 0;
//Other Methods
virtual bool directed() const = 0; //<2F><><EFBFBD><EFBFBD>ͼ
virtual bool weighted() const = 0; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩͼ
virtual vertexIterator<T>* iterator(int) = 0; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
};

View File

@@ -0,0 +1,14 @@
#include "adjacencyMatrix.h"
using namespace std;
int main() {
adjacencyMatrix<double> g(11);
edge<double> 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<double> 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;
}

View File

@@ -0,0 +1,8 @@
#pragma once
template <class T>
class vertexIterator {
public:
virtual ~vertexIterator() {}
virtual int next() = 0;
virtual bool hasNext() const = 0;
};