Add a constructor to Vector.h. Test class GraphMatrix, all tests passed. Dfs and Bfs remained to be done.
This commit is contained in:
@@ -34,6 +34,7 @@ public:
|
|||||||
//constructors
|
//constructors
|
||||||
Vector();
|
Vector();
|
||||||
Vector(int capacity);
|
Vector(int capacity);
|
||||||
|
Vector(int size, T const &value);
|
||||||
Vector(T* const A, int n) { copyfrom(A, 0, n); }
|
Vector(T* const A, int n) { copyfrom(A, 0, n); }
|
||||||
Vector(T* const A, int lo, int hi) { copyfrom(A, lo, hi); }
|
Vector(T* const A, int lo, int hi) { copyfrom(A, lo, hi); }
|
||||||
Vector(Vector<T> const &V) { copyfrom(V._elem, 0, V._size); }
|
Vector(Vector<T> const &V) { copyfrom(V._elem, 0, V._size); }
|
||||||
@@ -149,6 +150,15 @@ Vector<T>::Vector(int capacity) {
|
|||||||
_elem = new T[_capacity];
|
_elem = new T[_capacity];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Vector<T>::Vector(int size, T const &value){
|
||||||
|
_capacity = size << 1;
|
||||||
|
_size = size;
|
||||||
|
_elem = new T[_capacity];
|
||||||
|
for (int ix = 0; ix != _size; ++ix)
|
||||||
|
_elem[ix] = value;
|
||||||
|
}
|
||||||
|
|
||||||
//read-only interfaces
|
//read-only interfaces
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void Vector<T>::print() {
|
void Vector<T>::print() {
|
||||||
|
|||||||
@@ -66,6 +66,12 @@ void test_constructor() {
|
|||||||
assert(V5.getSize() == 2);
|
assert(V5.getSize() == 2);
|
||||||
assert(V5.getCapacity() == 4);
|
assert(V5.getCapacity() == 4);
|
||||||
|
|
||||||
|
Vector<int> V6(10, 0);
|
||||||
|
assert(V6.getSize() == 10);
|
||||||
|
assert(V6.getCapacity() == 20);
|
||||||
|
for (int ix = 0; ix != 10; ++ix)
|
||||||
|
assert(V6[ix] == 0);
|
||||||
|
|
||||||
cout << "test passed." << endl;
|
cout << "test passed." << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,12 @@
|
|||||||
|
|
||||||
template <typename Te>
|
template <typename Te>
|
||||||
class Edge{
|
class Edge{
|
||||||
|
public:
|
||||||
Te data;
|
Te data;
|
||||||
double weight = 1;
|
double weight = 1;
|
||||||
Etype type = UNDETERMINED;
|
Etype type = UNDETERMINED;
|
||||||
|
|
||||||
|
Edge() = default;
|
||||||
Edge(Te data) : data(data) {}
|
Edge(Te data) : data(data) {}
|
||||||
Edge(Te data, double w) : data(data), weight(w) {}
|
Edge(Te data, double w) : data(data), weight(w) {}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ typedef enum { UNDISCOVERED, DISCOVERED, VISITED } VStatus;
|
|||||||
typedef enum { UNDETERMINED, TREE, BACKWARD, FORWARD, CROSS } Etype;
|
typedef enum { UNDETERMINED, TREE, BACKWARD, FORWARD, CROSS } Etype;
|
||||||
|
|
||||||
//abstract class Graph
|
//abstract class Graph
|
||||||
template <typename Tv> template <typename Te>
|
template <typename Tv, typename Te>
|
||||||
class Graph{
|
class Graph{
|
||||||
private:
|
private:
|
||||||
void reset();
|
void reset();
|
||||||
@@ -38,11 +38,11 @@ public:
|
|||||||
|
|
||||||
//directed egde methods
|
//directed egde methods
|
||||||
virtual bool exists(int, int) = 0;
|
virtual bool exists(int, int) = 0;
|
||||||
virtual void insertEdge(Te const&, int, int, int) = 0;
|
virtual void insertEdge(Te const&, double, int, int) = 0;
|
||||||
virtual Te removeEdge(int, int) = 0;
|
virtual Te removeEdge(int, int) = 0;
|
||||||
virtual Etype& type(int, int) = 0;
|
virtual Etype& type(int, int) = 0;
|
||||||
virtual Te& edge(int, int) = 0;
|
virtual Te& edge(int, int) = 0;
|
||||||
virtual int& weight(int, int) = 0;
|
virtual double& weight(int, int) = 0;
|
||||||
|
|
||||||
//Graph related algorithms
|
//Graph related algorithms
|
||||||
void bfs(int);
|
void bfs(int);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#include "Vertex.h"
|
#include "Vertex.h"
|
||||||
#include "../chp2/Vector.h"
|
#include "../chp2/Vector.h"
|
||||||
|
|
||||||
template <typename Tv> template <typename Te>
|
template <typename Tv, typename Te>
|
||||||
class GraphMatrix: public Graph<Tv, Te>{
|
class GraphMatrix: public Graph<Tv, Te>{
|
||||||
private:
|
private:
|
||||||
Vector<Vertex<Tv>> V;
|
Vector<Vertex<Tv>> V;
|
||||||
@@ -29,60 +29,83 @@ public:
|
|||||||
int outDegree(int vertexId) { return V[vertexId].outDegree; }
|
int outDegree(int vertexId) { return V[vertexId].outDegree; }
|
||||||
int firstNeighbor(int vertexId);
|
int firstNeighbor(int vertexId);
|
||||||
int nextNeighbor(int vertexId, int curr);
|
int nextNeighbor(int vertexId, int curr);
|
||||||
int& dtime(int vertexId) { return V[vertexId].dtime; }
|
int& dtime(int vertexId) { return V[vertexId].dTime; }
|
||||||
int& ftime(int vertexId) { return V[vertexId].ftime; }
|
int& ftime(int vertexId) { return V[vertexId].fTime; }
|
||||||
int& parent(int vertexId) { return V[vertexId].parent; }
|
int& parent(int vertexId) { return V[vertexId].parent; }
|
||||||
int& priority(int vertexId) { return V[vertexId].priority; }
|
int& priority(int vertexId) { return V[vertexId].priority; }
|
||||||
VStatus& status(int vertexId) { return V[vertexId].status; }
|
VStatus& status(int vertexId) { return V[vertexId].status; }
|
||||||
|
|
||||||
//directed edge methods
|
//directed edge methods
|
||||||
bool exists(int src, int tail) { return E[src][tail] != nullptr; }
|
bool exists(int src, int tail) { return E[src][tail] != nullptr; }
|
||||||
void insertEdge(Te const &data, int weight, int src, int tail);
|
void insertEdge(Te const &data, int src, int tail) { insertEdge(data, 1, src, tail); }
|
||||||
|
void insertEdge(Te const &data, double weight, int src, int tail);
|
||||||
Te removeEdge(int src, int tail);
|
Te removeEdge(int src, int tail);
|
||||||
Etype& type(int src, int tail) { return E[src][tail]->type; }
|
Etype& type(int src, int tail) { return E[src][tail]->type; }
|
||||||
Te& edge(int src, int tail) { return E[src][tail]->data; }
|
Te& edge(int src, int tail) { return E[src][tail]->data; }
|
||||||
int& weight(int src, int tail) { return E[src][tail]->weight; }
|
double& weight(int src, int tail) { return E[src][tail]->weight; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//application interfaces
|
||||||
|
void graph_demo(GraphMatrix<char, int> &G);
|
||||||
|
|
||||||
/*---------------Implementations---------------*/
|
/*---------------Implementations---------------*/
|
||||||
|
|
||||||
//constructor
|
//constructor
|
||||||
template <typename Tv> template <typename Te>
|
template <typename Tv, typename Te>
|
||||||
GraphMatrix<Tv, Te>::GraphMatrix(){
|
GraphMatrix<Tv, Te>::GraphMatrix(){
|
||||||
num_of_vertices = 0;
|
num_of_vertices = 0;
|
||||||
num_of_edges = 0;
|
num_of_edges = 0;
|
||||||
|
}
|
||||||
|
|
||||||
V = Vector<Vertex<Tv>>();
|
//deconstructor
|
||||||
E = Vector<Vector<Edge<Te>>>();
|
template <typename Tv, typename Te>
|
||||||
|
GraphMatrix<Tv, Te>::~GraphMatrix(){
|
||||||
|
for (int ix = 0; ix != num_of_vertices; ++ix)
|
||||||
|
for (int jx = 0; jx != num_of_vertices; ++jx)
|
||||||
|
if (exists(ix, jx)) delete E[ix][jx];
|
||||||
}
|
}
|
||||||
|
|
||||||
//implementations of abstract Graph methods
|
//implementations of abstract Graph methods
|
||||||
|
|
||||||
//vertex methods
|
//vertex methods
|
||||||
template <typename Tv> template <typename Te>
|
template <typename Tv, typename Te>
|
||||||
int GraphMatrix<Tv, Te>::insertVertex(Tv const & data){
|
int GraphMatrix<Tv, Te>::insertVertex(Tv const & data){
|
||||||
V.push_back(Vertex<Tv>(data));
|
V.push_back(Vertex<Tv>(data));
|
||||||
for (int ix = 0; ix != num_of_vertices; ++ix) E[ix].push_back(nullptr);
|
for (int ix = 0; ix != num_of_vertices; ++ix) E[ix].push_back(nullptr);
|
||||||
E.push_back(Vector<Edge<Te>*>(nullptr, ++num_of_vertices));
|
E.push_back(Vector<Edge<Te>*>(++num_of_vertices, nullptr));
|
||||||
return num_of_vertices - 1;
|
return num_of_vertices - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Tv> template <typename Te>
|
template <typename Tv, typename Te>
|
||||||
Te GraphMatrix<Tv, Te>::removeVertex(int vertexId){
|
Tv GraphMatrix<Tv, Te>::removeVertex(int vertexId){
|
||||||
|
for (int ix = 0; ix != num_of_vertices; ++ix)
|
||||||
|
if (exists(vertexId, ix)) removeEdge(vertexId, ix);
|
||||||
|
|
||||||
for (int ix = 0; ix != num_of_vertices; ++ix) {
|
for (int ix = 0; ix != num_of_vertices; ++ix) {
|
||||||
//remove edges
|
if(exists(ix, vertexId)) removeEdge(ix, vertexId);
|
||||||
if(exists(ix, vertexId) removeEdge(ix, vertexId);
|
|
||||||
if(exists(vertexId, ix) removeEdge(vertexId, ix);
|
|
||||||
E[ix].pop(vertexId);
|
E[ix].pop(vertexId);
|
||||||
}
|
}
|
||||||
E.pop(vertexId);
|
E.pop(vertexId);
|
||||||
--num_of_vertices;
|
num_of_vertices--;
|
||||||
return V.pop(vertexId).data;
|
return V.pop(vertexId).data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Tv, typename Te>
|
||||||
|
int GraphMatrix<Tv, Te>::firstNeighbor(int vertexId) {
|
||||||
|
return nextNeighbor(vertexId, num_of_vertices);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Tv, typename Te>
|
||||||
|
int GraphMatrix<Tv, Te>::nextNeighbor(int vertexId, int curr) {
|
||||||
|
while(0 <= --curr){
|
||||||
|
if (exists(vertexId, curr)) break;
|
||||||
|
}
|
||||||
|
return curr;
|
||||||
|
}
|
||||||
|
|
||||||
//edge methods
|
//edge methods
|
||||||
template <typename Tv> template <typename Te>
|
template <typename Tv, typename Te>
|
||||||
void GraphMatrix<Tv, Te>::insertEdge(Te const &data, int weight, int src, int tail){
|
void GraphMatrix<Tv, Te>::insertEdge(Te const &data, double weight, int src, int tail){
|
||||||
if (src < 0 || src >= num_of_vertices || tail < 0 || tail >= num_of_vertices) return;
|
if (src < 0 || src >= num_of_vertices || tail < 0 || tail >= num_of_vertices) return;
|
||||||
if (exists(src, tail)) return;
|
if (exists(src, tail)) return;
|
||||||
|
|
||||||
@@ -90,14 +113,14 @@ void GraphMatrix<Tv, Te>::insertEdge(Te const &data, int weight, int src, int ta
|
|||||||
|
|
||||||
++num_of_edges;
|
++num_of_edges;
|
||||||
V[tail].inDegree++;
|
V[tail].inDegree++;
|
||||||
V[src].outDegree--;
|
V[src].outDegree++;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Tv> template <typename Te>
|
template <typename Tv, typename Te>
|
||||||
Te GraphMatrix<Tv, Te>::removeEdge(int src, int tail){
|
Te GraphMatrix<Tv, Te>::removeEdge(int src, int tail){
|
||||||
Te edgeBak = edge(src, tail);
|
Te edgeBak = edge(src, tail);
|
||||||
delete edge(src, tail);
|
delete E[src][tail];
|
||||||
edge(src, tail) = nullptr;
|
E[src][tail] = nullptr;
|
||||||
|
|
||||||
--num_of_edges;
|
--num_of_edges;
|
||||||
V[tail].inDegree--;
|
V[tail].inDegree--;
|
||||||
@@ -105,4 +128,20 @@ Te GraphMatrix<Tv, Te>::removeEdge(int src, int tail){
|
|||||||
return edgeBak;
|
return edgeBak;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//application interfaces
|
||||||
|
void graph_demo(GraphMatrix<char, int> &G) {
|
||||||
|
G = GraphMatrix<char, int>();
|
||||||
|
char *alphabet = "abcdefghij";
|
||||||
|
for (int ix = 0; ix != 10; ++ix)
|
||||||
|
G.insertVertex(alphabet[ix]);
|
||||||
|
G.insertEdge(1, 0, 1);
|
||||||
|
G.insertEdge(1, 0, 7);
|
||||||
|
G.insertEdge(1, 4, 2);
|
||||||
|
G.insertEdge(1, 5, 4);
|
||||||
|
G.insertEdge(1, 5, 3);
|
||||||
|
G.insertEdge(1, 6, 7);
|
||||||
|
G.insertEdge(1, 9, 6);
|
||||||
|
G.insertEdge(1, 3, 8);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ public:
|
|||||||
int inDegree = 0;
|
int inDegree = 0;
|
||||||
int outDegree = 0;
|
int outDegree = 0;
|
||||||
|
|
||||||
|
Vertex() = default;
|
||||||
Vertex(Tv data) : data(data) {}
|
Vertex(Tv data) : data(data) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
148
thu_dsa/chp6/testGraphMatrix.cpp
Normal file
148
thu_dsa/chp6/testGraphMatrix.cpp
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
#include "GraphMatrix.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <cassert>
|
||||||
|
using std::cout;
|
||||||
|
using std::endl;
|
||||||
|
|
||||||
|
void test_constructor();
|
||||||
|
void test_vertex_insert();
|
||||||
|
void test_vertex_delete();
|
||||||
|
void test_edge_insert();
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
cout << "Running tests" << endl;
|
||||||
|
|
||||||
|
test_constructor();
|
||||||
|
test_vertex_insert();
|
||||||
|
test_edge_insert();
|
||||||
|
test_vertex_delete();
|
||||||
|
|
||||||
|
cout << "All tests passed." << endl;
|
||||||
|
system("pause");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_constructor(){
|
||||||
|
GraphMatrix<int, int> G;
|
||||||
|
assert(G.num_of_edges == 0);
|
||||||
|
assert(G.num_of_vertices == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_vertex_insert(){
|
||||||
|
GraphMatrix<char, int> G;
|
||||||
|
G.insertVertex('a');
|
||||||
|
assert(G.num_of_vertices == 1);
|
||||||
|
assert(G.num_of_edges == 0);
|
||||||
|
assert(G.exists(0, 0) == false);
|
||||||
|
assert(G.vertex(0) == 'a');
|
||||||
|
assert(G.inDegree(0) == 0);
|
||||||
|
assert(G.outDegree(0) == 0);
|
||||||
|
assert(G.priority(0) == 0);
|
||||||
|
assert(G.dtime(0) == -1);
|
||||||
|
assert(G.ftime(0) == -1);
|
||||||
|
assert(G.parent(0) == -1);
|
||||||
|
|
||||||
|
G.insertVertex('b');
|
||||||
|
assert(G.num_of_vertices == 2);
|
||||||
|
assert(G.num_of_edges == 0);
|
||||||
|
assert(G.exists(0, 1) == false);
|
||||||
|
assert(G.exists(1, 1) == false);
|
||||||
|
assert(G.vertex(1) == 'b');
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_edge_insert(){
|
||||||
|
GraphMatrix<char, int> G;
|
||||||
|
graph_demo(G);
|
||||||
|
|
||||||
|
assert(G.num_of_edges == 8);
|
||||||
|
assert(G.edge(0, 1) == 1);
|
||||||
|
assert(G.weight(0, 1) == 1.);
|
||||||
|
assert(G.type(0, 1) == UNDETERMINED);
|
||||||
|
assert(G.exists(0, 7));
|
||||||
|
assert(G.exists(4, 2));
|
||||||
|
assert(G.exists(5, 4));
|
||||||
|
assert(G.exists(5, 3));
|
||||||
|
assert(G.exists(6, 7));
|
||||||
|
assert(G.exists(9, 6));
|
||||||
|
assert(G.exists(3, 8));
|
||||||
|
|
||||||
|
assert(!G.exists(1, 0));
|
||||||
|
assert(!G.exists(7, 0));
|
||||||
|
assert(!G.exists(2, 4));
|
||||||
|
assert(!G.exists(4, 5));
|
||||||
|
assert(!G.exists(3, 5));
|
||||||
|
assert(!G.exists(7, 6));
|
||||||
|
assert(!G.exists(6, 9));
|
||||||
|
assert(!G.exists(8, 3));
|
||||||
|
|
||||||
|
assert(G.inDegree(0) == 0);
|
||||||
|
assert(G.inDegree(1) == 1);
|
||||||
|
assert(G.inDegree(2) == 1);
|
||||||
|
assert(G.inDegree(3) == 1);
|
||||||
|
assert(G.inDegree(4) == 1);
|
||||||
|
assert(G.inDegree(5) == 0);
|
||||||
|
assert(G.inDegree(6) == 1);
|
||||||
|
assert(G.inDegree(7) == 2);
|
||||||
|
assert(G.inDegree(8) == 1);
|
||||||
|
assert(G.inDegree(9) == 0);
|
||||||
|
|
||||||
|
assert(G.outDegree(0) == 2);
|
||||||
|
assert(G.outDegree(1) == 0);
|
||||||
|
assert(G.outDegree(2) == 0);
|
||||||
|
assert(G.outDegree(3) == 1);
|
||||||
|
assert(G.outDegree(4) == 1);
|
||||||
|
assert(G.outDegree(5) == 2);
|
||||||
|
assert(G.outDegree(6) == 1);
|
||||||
|
assert(G.outDegree(7) == 0);
|
||||||
|
assert(G.outDegree(8) == 0);
|
||||||
|
assert(G.outDegree(9) == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_vertex_delete(){
|
||||||
|
GraphMatrix<char, int> G;
|
||||||
|
graph_demo(G);
|
||||||
|
|
||||||
|
G.removeVertex(0);
|
||||||
|
assert(G.num_of_vertices == 9);
|
||||||
|
assert(G.num_of_edges == 6);
|
||||||
|
assert(G.inDegree(0) == 0);
|
||||||
|
assert(G.inDegree(1) == 1);
|
||||||
|
assert(G.inDegree(2) == 1);
|
||||||
|
assert(G.inDegree(3) == 1);
|
||||||
|
assert(G.inDegree(4) == 0);
|
||||||
|
assert(G.inDegree(5) == 1);
|
||||||
|
assert(G.inDegree(6) == 1);
|
||||||
|
assert(G.inDegree(7) == 1);
|
||||||
|
assert(G.inDegree(8) == 0);
|
||||||
|
|
||||||
|
assert(G.outDegree(0) == 0);
|
||||||
|
assert(G.outDegree(1) == 0);
|
||||||
|
assert(G.outDegree(2) == 1);
|
||||||
|
assert(G.outDegree(3) == 1);
|
||||||
|
assert(G.outDegree(4) == 2);
|
||||||
|
assert(G.outDegree(5) == 1);
|
||||||
|
assert(G.outDegree(6) == 0);
|
||||||
|
assert(G.outDegree(7) == 0);
|
||||||
|
assert(G.outDegree(8) == 1);
|
||||||
|
|
||||||
|
G.removeVertex(5);
|
||||||
|
assert(G.num_of_vertices == 8);
|
||||||
|
assert(G.num_of_edges == 4);
|
||||||
|
assert(G.inDegree(0) == 0);
|
||||||
|
assert(G.inDegree(1) == 1);
|
||||||
|
assert(G.inDegree(2) == 1);
|
||||||
|
assert(G.inDegree(3) == 1);
|
||||||
|
assert(G.inDegree(4) == 0);
|
||||||
|
assert(G.inDegree(5) == 0);
|
||||||
|
assert(G.inDegree(6) == 1);
|
||||||
|
assert(G.inDegree(7) == 0);
|
||||||
|
|
||||||
|
assert(G.outDegree(0) == 0);
|
||||||
|
assert(G.outDegree(1) == 0);
|
||||||
|
assert(G.outDegree(2) == 1);
|
||||||
|
assert(G.outDegree(3) == 1);
|
||||||
|
assert(G.outDegree(4) == 2);
|
||||||
|
assert(G.outDegree(5) == 0);
|
||||||
|
assert(G.outDegree(6) == 0);
|
||||||
|
assert(G.outDegree(7) == 0);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user