I just started using C++, and I was wondering if my code fits the standards so far. Specifically, I was wondering if I did the addEdge
, isConnected
, and getShortestPathForm methods
correctly. For instance, are the parameters correct as Vector<T> &v
or should it be Vector<T> *v
or Vector<T> v
?
//Graph.h
#ifndef GRAPH_H
#define GRAPH_H
#include <vector>
#include <string>
#include <queue>
template <typename T>
class Graph;
template <typename K>
class Vertex;
template <typename T>
class Neighbor {
friend class Vertex<T>;
friend class Graph<T>;
private:
int vertexIndex;
Neighbor *next;
public:
Neighbor(int vIndex, Neighbor *n) : vertexIndex(vIndex), next(n) {}
};
template <typename T>
class Vertex {
friend class Graph<T>;
private:
T data;
int index;
Neighbor<T> *adjLL;
public:
Vertex(const T &val, const int i) : data(val), index(i), adjLL(NULL) {}
};
typedef enum GraphType {
GraphTypeDirected,
GraphTypeUndirected
} GraphType;
template <typename T>
class Graph {
private:
std::vector< Vertex<T> > vertices;
GraphType graphType;
int counter;
public:
Graph(const GraphType type) : graphType(type), counter(0) {}
Graph(const Graph &);
Vertex<T> *addVertex(const T &);
void addEdge(Vertex<T> &, Vertex<T> &);
bool isConnected(const Vertex<T> &, const Vertex<T> &);
std::string getShortestPathFrom(Vertex<T> &, Vertex<T> &);
};
template <typename T>
Vertex<T> *Graph<T>::addVertex(const T &data)
{
Vertex<T> *v = new Vertex<T>(data, counter++);
vertices.push_back(*v);
return v;
}
template <typename T>
void Graph<T>::addEdge(Vertex<T> &v1, Vertex<T> &v2)
{
Neighbor<T> *adjLL1 = v1.adjLL;
Neighbor<T> *adjLL2 = v2.adjLL;
v1.adjLL = new Neighbor<T>(v2.index, v1.adjLL);
v2.adjLL = new Neighbor<T>(v1.index, v2.adjLL);
vertices.at(v1.index) = v1;
vertices.at(v2.index) = v2;
}
template <typename T>
bool Graph<T>::isConnected(const Vertex<T> &v1, const Vertex<T> &v2)
{
Neighbor<T> *curr = v1.adjLL;
while (curr != NULL) {
if (curr->vertexIndex == v2.index)
return true;
curr = curr->next;
}
return false;
}
template <typename T>
std::string Graph<T>::getShortestPathFrom(Vertex<T> &v1, Vertex<T> &v2)
{
std::queue<Vertex<T> > q;
q.push(v1);
bool *seen = new bool[vertices.size()];
for (int i = 0; i < vertices.size(); i++)
seen[i] = false;
seen[v1.index] = true;
while (!q.empty()) {
Vertex<T> v = q.front();
Neighbor<T> *curr = v.adjLL;
while (curr != NULL) {
if (!seen[curr->vertexIndex]) {
seen[curr->vertexIndex] = true;
q.push(vertices.at(curr->vertexIndex));
if (vertices.at(curr->vertexIndex).data == v2.data) {
std::string temp;
while (!q.empty()) {
printf("%d\n", q.front().data);
temp += q.front().data;
q.pop();
}
return temp;
}
}
curr = curr->next;
}
q.pop();
}
return "Path Not Found";
}
#endif
//main.cpp
#include <stdio.h>
#include <string>
#include <iostream>
#include "Graph.h"
using namespace std;
int main(int argc, const char *argv[])
{
Graph<int> *graph = new Graph<int>(GraphTypeUndirected);
Vertex<int> *v1 = graph->addVertex(10);
Vertex<int> *v2 = graph->addVertex(15);
Vertex<int> *v3 = graph->addVertex(20);
Vertex<int> *v4 = graph->addVertex(25);
Vertex<int> *v5 = graph->addVertex(30);
graph->addEdge(*v1, *v2);
graph->addEdge(*v1, *v3);
graph->addEdge(*v1, *v4);
bool c = graph->isConnected(*v1, *v3);
std::string s = graph->getShortestPathFrom(*v1, *v3);
printf("%s", s.c_str());
}