I have a suffix tree, each node of this tree is a struct
struct state {
int len, link;
map<char,int> next; };
state[100000] st;
I need to make dfs for each node and get all strings which I can reach, but I don't know how to make.
This is my dfs function
void getNext(int node){
for(map<char,int>::iterator it = st[node].next.begin();it != st[node].next.end();it++){
getNext(it->second);
}
}
It will be perfect if I can make something like
map<int,vector<string> >
where int is a node of my tree and vector strings which I can reach
now it works
void createSuffices(int node){//, map<int, vector<string> > &suffices) {
if (suffices[sz - 1].size() == 0 && (node == sz - 1)) {
// node is a leaf
// add a vector for this node containing just
// one element: the empty string
//suffices[node] = new vector<string>
//suffices.add(node, new vector<string>({""}));
vector<string> r;
r.push_back(string());
suffices[node] = r;
} else {
// node is not a leaf
// create the vector that will be built up
vector<string> v;
// loop over each child
for(map<char,int>::iterator it = st[node].next.begin();it != st[node].next.end();it++){
createSuffices(it->second);
vector<string> t = suffices[it->second];
for(int i = 0; i < t.size(); i ++){
v.push_back(string(1,it->first) + t[i]);
}
}
suffices[node] = v;
}
}
You can pass the map<int, vector<string>> together with your depth first search. When a recursive call returns from a certain node n, you know that all suffices from that node are ready. My C++ skills are too limited, so I'll write it in pseudo-code:
void createSuffices(int node, map<int, vector<string>> suffices) {
if (st[node].next.empty()) {
// node is a leaf
// add a vector for this node containing just
// one element: the empty string
suffices.add(node, new vector<string>({""}));
} else {
// node is not a leaf
// create the vector that will be built up
vector<string> v;
// loop over each child
foreach pair<char, int> p in st[node].next {
// handle the child
createSuffices(p.second, suffices);
// prepend the character to all suffices of the child
foreach string suffix in suffices(p.second) {
v.add(concatenate(p.first, suffix));
}
}
// add the created vector to the suffix map
suffices.add(node, v);
}
}
Related
The premise of the project I am doing is to make skip lists with iterators and not pointers. I have created a vector of lists of nodes. And in the node struct, it contains an iterator which is supposed to be the iterator of the list below it while preserving position. The problem is when I create a new node, set its below iterator to the list below's iterator, and later try to access it by de referencing it, it seg faults. I think this is because the iterator is not initialized and it cant be dereferenced as it does not appear to be a bounds issue.
struct Node // in header file
{
int value;
list<Node>::iterator below;
Node(int v, list<Node>::iterator b){
value = v;
below = b;
}
Node(){}
Node(int v){
value = v;
}
};
vector<list<Node>> skipList; //this is the skipList initialized in the header
//insert called to add numbers to skiplist
void SkipLists::insert(int num){
list<Node>::iterator loc;
if(skipList.empty()){
list<Node> nodes;
nodes.push_back(Node(num));
skipList.push_back(nodes);
}else{
loc = insertPlace(num, skipList[skipList.size()-1].begin(), skipList.size() -1);
skipList[0].insert(loc, Node(num));
}
cout << "1. " << *this << "\n\n\n";
stack(num, loc);
//this if statement also segfaults
if(skipList.size() > 1){
cout << (*(skipList[1].front().below)).value;
}
}
//in insertPlace function it segfaults on the while loop's only if a recursive call is made. Meaning the previous value added to the skiplist had height to it. It segfaults when dereferencing it. I tested this by moving it out of the while loop.
list<Node>::iterator SkipLists::insertPlace(int num, list<Node>::iterator it, int height){
if(height == 0){
while(it != skipList[0].end() && skipList[0].size() > 0 && num > (*it).value){ // problem: likely not returning a good (*it).below or never setting it properly.
it++;
}
return it;
}
while(it != skipList[height].end() && skipList[height].size() > 0 && num > (*it).value){
cout << "he\n";
it++;
cout << "lo\n";
}
return insertPlace(num, (*it).below, --height);
}
stack is used to add vertical elements in the skip list based on probability. This is where the nodes are given a "below" iterator.
void SkipLists::stack(int num, list<Node>::iterator loc){
int flip = rand() % 2;
int count = 1;
list<Node>::iterator prev = loc;
list<Node>::iterator it;
while(flip == 1){
count++;
flip = rand() % 2;
if(skipList.size() < count){
list<Node> nodes;
nodes.push_back(Node(num, prev));
skipList.push_back(nodes);
prev = skipList[skipList.size()-1].begin();
}else{
it = skipList[count-1].begin();
while(it != skipList[count -1].end() && num > (*it).value){
it++;
}
prev = skipList[count -1].insert(it,Node(num, prev));
}
}
}
vector<list<Node>> skipList; is dangerous. If a new list is added then the vector might relocate all other lists and that invalidates all stored iterators. Even though the lists can be move constructed in a new place, they are still new objects and comparing .end() with a iterator obtained from another object is undefined behaviour.
I think that is what eventually happens in your code.
[Probably not a proper answer, but its too long for a comment and I won't debug author's code to make sure.]
One obvious error is your Node class implementation.
If you look at your Node constructor that takes a single int, you failed to initialize the below iterator. Thus any access in attempting to dereference below will result in undefined behavior occurring, as you're doing in this line:
cout << (*(skipList[1].front().below)).value;
If the skip list is empty, you will see that your code will produce Node objects where below is not initialized.
Here is a stripped down, simple example using more or less the code you posted:
#include <list>
#include <vector>
#include <iostream>
struct Node // in header file
{
int value;
std::list<Node>::iterator below;
Node(int v, std::list<Node>::iterator b) {
value = v;
below = b;
}
Node() {}
Node(int v) {
value = v;
}
};
class SkipLists
{
private:
std::vector<std::list<Node>> skipList;
public:
void insert(int num);
std::list<Node>::iterator insertPlace(int num, std::list<Node>::iterator it, int height);
void stack(int num, std::list<Node>::iterator loc);
};
using namespace std;
void SkipLists::insert(int num)
{
list<Node>::iterator loc;
if (skipList.empty())
{
list<Node> nodes;
nodes.push_back(Node(num));
skipList.push_back(nodes);
}
else
{
loc = insertPlace(num, skipList[skipList.size() - 1].begin(), skipList.size() - 1);
skipList[0].insert(loc, Node(num));
}
stack(num, loc);
//this if statement also segfaults
if (skipList.size() > 1) {
cout << (*(skipList[1].front().below)).value;
}
}
list<Node>::iterator SkipLists::insertPlace(int num, list<Node>::iterator it, int height)
{
if (height == 0) {
while (it != skipList[0].end() && skipList[0].size() > 0 && num > (*it).value)
{
it++;
}
return it;
}
while (it != skipList[height].end() && skipList[height].size() > 0 && num > (*it).value)
{
cout << "he\n";
it++;
cout << "lo\n";
}
return insertPlace(num, (*it).below, --height);
}
void SkipLists::stack(int num, list<Node>::iterator loc) {
int flip = rand() % 2;
int count = 1;
list<Node>::iterator prev = loc;
list<Node>::iterator it;
while (flip == 1) {
count++;
flip = rand() % 2;
if (skipList.size() < count) {
list<Node> nodes;
nodes.push_back(Node(num, prev));
skipList.push_back(nodes);
prev = skipList[skipList.size() - 1].begin();
}
else {
it = skipList[count - 1].begin();
while (it != skipList[count - 1].end() && num > (*it).value) {
it++;
}
prev = skipList[count - 1].insert(it, Node(num, prev));
}
}
}
// Test
int main()
{
SkipLists s;
s.insert(4);
}
You will see that below is not initialized on the line you are saying your application crashes on when running this very small sample.
You also have the same issue with the Node default constructor where both the value and below members are not initialized. When you create an object, all the members should be in some sort of valid state, or "null" in some way. For iterators, it is harder to do this since there isn't a "null" iterator, unless you can set the iterator to an existing list's end() iterator.
Basically you need to design your class so that you are sure that the iterator is pointing somewhere valid, or some other means of indicating that the iterator should not be dereferenced.
I was looking into BFS search code provide in here:
// Program to print BFS traversal from a given
// source vertex. BFS(int s) traverses vertices
// reachable from s.
#include<iostream>
#include <list>
using namespace std;
// This class represents a directed graph using
// adjacency list representation
class Graph
{
int V; // No. of vertices
// Pointer to an array containing adjacency
// lists
list<int> *adj;
public:
Graph(int V); // Constructor
// function to add an edge to graph
void addEdge(int v, int w);
// prints BFS traversal from a given source s
void BFS(int s);
};
Graph::Graph(int V)
{
this->V = V;
adj = new list<int>[V];
}
void Graph::addEdge(int v, int w)
{
adj[v].push_back(w); // Add w to v’s list.
}
void Graph::BFS(int s)
{
// Mark all the vertices as not visited
bool *visited = new bool[V];
for(int i = 0; i < V; i++)
visited[i] = false;
// Create a queue for BFS
list<int> queue;
// Mark the current node as visited and enqueue it
visited[s] = true;
queue.push_back(s);
// 'i' will be used to get all adjacent
// vertices of a vertex
list<int>::iterator i;
while(!queue.empty())
{
// Dequeue a vertex from queue and print it
s = queue.front();
cout << s << " ";
queue.pop_front();
// Get all adjacent vertices of the dequeued
// vertex s. If a adjacent has not been visited,
// then mark it visited and enqueue it
for (i = adj[s].begin(); i != adj[s].end(); ++i)
{
if (!visited[*i])
{
visited[*i] = true;
queue.push_back(*i);
}
}
}
}
// Driver program to test methods of graph class
int main()
{
// Create a graph given in the above diagram
Graph g(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(2, 0);
g.addEdge(2, 3);
g.addEdge(3, 3);
cout << "Following is Breadth First Traversal "
<< "(starting from vertex 2) \n";
g.BFS(2);
return 0;
}
In the constructor of Graph class they created a adjacency list in the heap but they never use a delete to free the memory. My question is as following
a) Is there any chance of memory leak?
If there is any memory leak how could we solve the problem?
Yes there are leaks.
Leak 1 is new list<int>[V];
Leak 2 is new bool[V];
Looks like some guy with Java or C# background wrote this piece of code. To fix the leaks use delete[] in the function void Graph::BFS(int s) also use a destructor to delete the list.
Then, you might consider std::shared_ptr.
Is there any chance of memory leak?
Yes, there is a high chance for a memory leak.
If there is any memory leak how could we solve the problem?
Generally, this can be solved by implementing a destructor. Then again, according to the rule of three, we would need a copy-constructor as well, just in case an end user decides to copy one list to another.
But we could actually sidestep this by not dynamically-allocating in the first place! Let's reimplement with std::vector:
class Graph
{
int V;
vector<list<int>> adj;
public:
Graph(int V);
// ...
};
Graph::Graph(int V)
{
this->V = V;
adj.assign(V, list<int>()); // std::vector::assign
}
void Graph::BFS(int s)
{
// Mark all the vertices as not visited
vector<bool> visited(V); // see note below *
for(int i = 0; i < V; i++)
visited[i] = false;
// Create a queue for BFS
list<int> queue;
// Mark the current node as visited and enqueue it
visited[s] = true;
queue.push_back(s);
// 'i' will be used to get all adjacent
// vertices of a vertex
list<int>::iterator i;
while(!queue.empty())
{
// Dequeue a vertex from queue and print it
s = queue.front();
cout << s << " ";
queue.pop_front();
// Get all adjacent vertices of the dequeued
// vertex s. If a adjacent has not been visited,
// then mark it visited and enqueue it
for (i = adj[s].begin(); i != adj[s].end(); ++i)
{
if (!visited[*i])
{
visited[*i] = true;
queue.push_back(*i);
}
}
}
}
There are a ton of other minor issues with this code, but I shall leave that as an exercise for the reader.
*Note: vector<bool> isn't your normal vector.
So, I implemented the DFS in an iterative manner by the following method:
void dfsiter (graph * mygraph, int foo, bool arr[])
{
stack <int> mystack;
mystack.push(foo);
while (mystack.empty() == false)
{
int k = mystack.top();
mystack.pop();
if (arr[k] == false)
{
cout<<k<<"\t";
arr[k] = true;
auto it = mygraph->edges[k].begin();
while (it != mygraph->edges[k].end())
{
if (arr[*it] == false)
{
mystack.push(*it);
}
it++;
}
}
}
}
The above code works completely fine. Now, I want to detect cycles in an undirected graph using the above code (Iterative DFS). Now, I read that, If an unexplored edge leads to a node visited before, then the graph contains a cycle. Therefore, I just want to ask you, how do I exactly keep track of all this?
I have taken my graph to be like this:
class graph
{
public:
int vertices;
vector < vector<int> > edges;
};
Should I change the above to:
class graph
{
public:
int vertices;
vector < vector<pair<int,bool> > edges;
};
Where the bool for each edge will be marked true? And what changes will I need to do in the above code for DFS for detecting the cycle? I tried but I couldn't really think of a way of doing it. Thanks!
You can store a "father" node f in DFS tree for each vertex v, i.e. the vertex from which DFS came to the vertex v. It can be stored in the stack for example. In this case you store pairs in stack, first value is the vertex v and the second one is its father f.
An undirected graph has a cycle if and only if you meet an edge vw going to already visited vertex w, which is not the father of v.
You can see the modified and cleaned code below.
bool hascycle (graph * mygraph, int start, bool visited[])
{
stack <pair<int, int> > mystack;
mystack.push(make_pair(start, -1));
visited[start] = true;
while (!mystack.empty())
{
int v = mystack.top().first;
int f = mystack.top().second;
mystack.pop();
const auto &edges = mygraph->edges[v];
for (auto it = edges.begin(); it != edges.end(); it++)
{
int w = *it;
if (!visited[w])
{
mystack.push(make_pair(w, v));
visited[w] = true;
}
else if (w != f)
return true;
}
}
return false;
}
Note: if the graph is disconnected, then you must start DFS from several vertices, ensuring that the whole graph is visited. It can be done in O(V + E) total time.
This question is a continuum from this one
I have a vector of lists in my Node class that are not being passed to other functions.
Here is the Node.h
#include "MyGraph.h"
//The Node Class will take the information from the graph class and
//convert the information into a format so we can perform DFS on our
//graph.
enum VertexState { White, Gray, Black };
class Node {
private:
string nodeId;
VertexState status; //whether or not the vertex Node has been visited or not
vector<Node> nodeList;
vector<list<Node> > *edgeList;
public:
Node(): nodeId(), status(){}
//copy constructor
Node(string vertex){
nodeId=vertex;
status = White;
}
~Node(){}
//Setter and Getter methods for our class variables
void setId(string vertex){
nodeId = vertex;
}
void setStatus(VertexState newStatus){
status = newStatus;
}
string getNodeId(){
return nodeId;
}
VertexState getStatus(){
//status == White then it is not visited
//status == Gray its being processed
//status == Black then it has been visited
return status;
}
vector<Node> getNodeList(){
return nodeList;
}
vector<list<Node> > getEdgeList(){
return *edgeList;
}
//create nodes from vertex list in the graph object
void createNodeList(MyGraph graphObject){
vector<string> vertexList;
vertexList = graphObject.getVertexList();
vector<string>::iterator it;
vector<Node>placeNodeList;
for (it = vertexList.begin(); it !=vertexList.end(); it++){
Node newNode(*it);
placeNodeList.push_back(newNode);
}
nodeList = placeNodeList;
cout << "Size of initial nodeList: " << nodeList.size()<<endl;
}
//creates container for edge lists from the graph object
void createEdgeList(MyGraph graphObject){
vector<list<string> > newEdgeList;
newEdgeList = graphObject.getEdgeList();
vector<list<Node> > myEdgeList;
vector<list<string> >::iterator it;
for (it = newEdgeList.begin() ; it != newEdgeList.end(); it++) {
list<string> edgeString;
list<string>::iterator eIt;
edgeString =*it;
list<Node> edgeContainer; //creates a list container to be pushed on to our edgeList variable
for (eIt = edgeString.begin(); eIt != edgeString.end(); eIt++) {
Node newNode(*eIt);
edgeContainer.push_back(newNode);
}
myEdgeList.push_back(edgeContainer);
}
edgeList = &myEdgeList;
cout << "Size of intial edgeList: "<<edgeList->size() <<endl;
}
//The operational methods that will work on the Nodes of the graph
vector<Node> dephtFirstSearch(Node vertex);//will determine if our graph is connected.
vector<Node> DFS2(vector<Node> copyNodeList);
bool isGraphConnected(vector<Node> nodeList);
bool isEdgeConnected(Node vertex1, Node vertex2);//will determine if there is an edge between two nodes
bool findElementaryCycles();
void findArticulationPoints();
void removeVertex(Node myNode, vector<Node>copyNodeList, vector<list<Node> >copyEdgeList);
};
When I try to call vector edgeList in my other functions using:
edgeList->empty;
The function is empty when it shouldn't be.
The createEdgeList function is called every time i need it to be used so its not empty.
How do I pass the data from my private variable to the functions?
vector<list<Node> > myEdgeList;
...
edgeList = &myEdgeList;
You are storing a pointer to a local variable - this is at best undefined behavior.
Why dont you make edgelist a normal vector and add to it directly in createEdgeList
I was wondering about a quick to write implementation of a graph in c++. I need the data structure to be easy to manipulate and use graph algorithms(such as BFS,DFS, Kruskal, Dijkstra...).
I need this implementation for an algorithms Olympiad, so the easier to write the data structure the better.
Can you suggest such DS(main structs or classes and what will be in them). I know that an Adjacency list and Adjacency matrix are the main possibilities, but I mean a more detailed code sample.
For example I thought about this DS last time I had to implement a graph for DFS:
struct Edge {
int start;
int end;
struct Edge* nextEdge;
}
and then used a array of size n containing in its i'th place the Edge List(struct Edge) representing the edges starting in the i'th node.
but when trying to DFS on this graph I had to write a 50 line code with about 10 while loops.
What 'good' implementations are there?
Below is a implementation of Graph Data Structure in C++ as Adjacency List.
I have used STL vector for representation of vertices and STL pair for denoting edge and destination vertex.
#include <iostream>
#include <vector>
#include <map>
#include <string>
using namespace std;
struct vertex {
typedef pair<int, vertex*> ve;
vector<ve> adj; //cost of edge, destination vertex
string name;
vertex(string s) : name(s) {}
};
class graph
{
public:
typedef map<string, vertex *> vmap;
vmap work;
void addvertex(const string&);
void addedge(const string& from, const string& to, double cost);
};
void graph::addvertex(const string &name)
{
vmap::iterator itr = work.find(name);
if (itr == work.end())
{
vertex *v;
v = new vertex(name);
work[name] = v;
return;
}
cout << "\nVertex already exists!";
}
void graph::addedge(const string& from, const string& to, double cost)
{
vertex *f = (work.find(from)->second);
vertex *t = (work.find(to)->second);
pair<int, vertex *> edge = make_pair(cost, t);
f->adj.push_back(edge);
}
It really depends on what algorithms you need to implement, there is no silver bullet (and that's shouldn't be a surprise... the general rule about programming is that there's no general rule ;-) ).
I often end up representing directed multigraphs using node/edge structures with pointers... more specifically:
struct Node
{
... payload ...
Link *first_in, *last_in, *first_out, *last_out;
};
struct Link
{
... payload ...
Node *from, *to;
Link *prev_same_from, *next_same_from,
*prev_same_to, *next_same_to;
};
In other words each node has a doubly-linked list of incoming links and a doubly-linked list of outgoing links. Each link knows from and to nodes and is at the same time in two different doubly-linked lists: the list of all links coming out from the same from node and the list of all links arriving at the same to node.
The pointers prev_same_from and next_same_from are used when following the chain of all the links coming out from the same node; the pointers prev_same_to and next_same_to are instead used when managing the chain of all the links pointing to the same node.
It's a lot of pointer twiddling (so unless you love pointers just forget about this) but query and update operations are efficient; for example adding a node or a link is O(1), removing a link is O(1) and removing a node x is O(deg(x)).
Of course depending on the problem, payload size, graph size, graph density this approach can be way overkilling or too much demanding for memory (in addition to payload you've 4 pointers per node and 6 pointers per link).
A similar structure full implementation can be found here.
This question is ancient but for some reason I can't seem to get it out of my mind.
While all of the solutions do provide an implementation of graphs, they are also all very verbose. They are simply not elegant.
Instead of inventing your own graph class all you really need is a way to tell that one point is connected to another -- for that, std::map and std::unordered_map work perfectly fine. Simply, define a graph as a map between nodes and lists of edges. If you don't need extra data on the edge, a list of end nodes will do just fine.
Thus a succinct graph in C++, could be implemented like so:
using graph = std::map<int, std::vector<int>>;
Or, if you need additional data,
struct edge {
int nodes[2];
float cost; // add more if you need it
};
using graph = std::map<int, std::vector<edge>>;
Now your graph structure will plug nicely into the rest of the language and you don't have to remember any new clunky interface -- the old clunky interface will do just fine.
No benchmarks, but I have a feeling this will also outperform the other suggestions here.
NB: the ints are not indices -- they are identifiers.
The most common representations are probably these two:
Adjacency list
Adjacency matrix
Of these two the adjacency matrix is the simplest, as long as you don't mind having a (possibly huge) n * n array, where n is the number of vertices. Depending on the base type of the array, you can even store edge weights for use in e.g. shortest path discovery algorithms.
I prefer using an adjacency list of Indices ( not pointers )
typedef std::vector< Vertex > Vertices;
typedef std::set <int> Neighbours;
struct Vertex {
private:
int data;
public:
Neighbours neighbours;
Vertex( int d ): data(d) {}
Vertex( ): data(-1) {}
bool operator<( const Vertex& ref ) const {
return ( ref.data < data );
}
bool operator==( const Vertex& ref ) const {
return ( ref.data == data );
}
};
class Graph
{
private :
Vertices vertices;
}
void Graph::addEdgeIndices ( int index1, int index2 ) {
vertices[ index1 ].neighbours.insert( index2 );
}
Vertices::iterator Graph::findVertexIndex( int val, bool& res )
{
std::vector<Vertex>::iterator it;
Vertex v(val);
it = std::find( vertices.begin(), vertices.end(), v );
if (it != vertices.end()){
res = true;
return it;
} else {
res = false;
return vertices.end();
}
}
void Graph::addEdge ( int n1, int n2 ) {
bool foundNet1 = false, foundNet2 = false;
Vertices::iterator vit1 = findVertexIndex( n1, foundNet1 );
int node1Index = -1, node2Index = -1;
if ( !foundNet1 ) {
Vertex v1( n1 );
vertices.push_back( v1 );
node1Index = vertices.size() - 1;
} else {
node1Index = vit1 - vertices.begin();
}
Vertices::iterator vit2 = findVertexIndex( n2, foundNet2);
if ( !foundNet2 ) {
Vertex v2( n2 );
vertices.push_back( v2 );
node2Index = vertices.size() - 1;
} else {
node2Index = vit2 - vertices.begin();
}
assert( ( node1Index > -1 ) && ( node1Index < vertices.size()));
assert( ( node2Index > -1 ) && ( node2Index < vertices.size()));
addEdgeIndices( node1Index, node2Index );
}
There can be an even simpler representation assuming that one has to only test graph algorithms not use them(graph) else where. This can be as a map from vertices to their adjacency lists as shown below :-
#include<bits/stdc++.h>
using namespace std;
/* implement the graph as a map from the integer index as a key to the adjacency list
* of the graph implemented as a vector being the value of each individual key. The
* program will be given a matrix of numbers, the first element of each row will
* represent the head of the adjacency list and the rest of the elements will be the
* list of that element in the graph.
*/
typedef map<int, vector<int> > graphType;
int main(){
graphType graph;
int vertices = 0;
cout << "Please enter the number of vertices in the graph :- " << endl;
cin >> vertices;
if(vertices <= 0){
cout << "The number of vertices in the graph can't be less than or equal to 0." << endl;
exit(0);
}
cout << "Please enter the elements of the graph, as an adjacency list, one row after another. " << endl;
for(int i = 0; i <= vertices; i++){
vector<int> adjList; //the vector corresponding to the adjacency list of each vertex
int key = -1, listValue = -1;
string listString;
getline(cin, listString);
if(i != 0){
istringstream iss(listString);
iss >> key;
iss >> listValue;
if(listValue != -1){
adjList.push_back(listValue);
for(; iss >> listValue; ){
adjList.push_back(listValue);
}
graph.insert(graphType::value_type(key, adjList));
}
else
graph.insert(graphType::value_type(key, adjList));
}
}
//print the elements of the graph
cout << "The graph that you entered :- " << endl;
for(graphType::const_iterator iterator = graph.begin(); iterator != graph.end(); ++iterator){
cout << "Key : " << iterator->first << ", values : ";
vector<int>::const_iterator vectBegIter = iterator->second.begin();
vector<int>::const_iterator vectEndIter = iterator->second.end();
for(; vectBegIter != vectEndIter; ++vectBegIter){
cout << *(vectBegIter) << ", ";
}
cout << endl;
}
}
Here is a basic implementation of a graph.
Note: I use vertex which is chained to next vertex. And each vertex has a list pointing to adjacent nodes.
#include <iostream>
using namespace std;
// 1 ->2
// 1->4
// 2 ->3
// 4->3
// 4 -> 5
// Adjacency list
// 1->2->3-null
// 2->3->null
//4->5->null;
// Structure of a vertex
struct vertex {
int i;
struct node *list;
struct vertex *next;
};
typedef struct vertex * VPTR;
// Struct of adjacency list
struct node {
struct vertex * n;
struct node *next;
};
typedef struct node * NODEPTR;
class Graph {
public:
// list of nodes chained together
VPTR V;
Graph() {
V = NULL;
}
void addEdge(int, int);
VPTR addVertex(int);
VPTR existVertex(int i);
void listVertex();
};
// If vertex exist, it returns its pointer else returns NULL
VPTR Graph::existVertex(int i) {
VPTR temp = V;
while(temp != NULL) {
if(temp->i == i) {
return temp;
}
temp = temp->next;
}
return NULL;
}
// Add a new vertex to the end of the vertex list
VPTR Graph::addVertex(int i) {
VPTR temp = new(struct vertex);
temp->list = NULL;
temp->i = i;
temp->next = NULL;
VPTR *curr = &V;
while(*curr) {
curr = &(*curr)->next;
}
*curr = temp;
return temp;
}
// Add a node from vertex i to j.
// first check if i and j exists. If not first add the vertex
// and then add entry of j into adjacency list of i
void Graph::addEdge(int i, int j) {
VPTR v_i = existVertex(i);
VPTR v_j = existVertex(j);
if(v_i == NULL) {
v_i = addVertex(i);
}
if(v_j == NULL) {
v_j = addVertex(j);
}
NODEPTR *temp = &(v_i->list);
while(*temp) {
temp = &(*temp)->next;
}
*temp = new(struct node);
(*temp)->n = v_j;
(*temp)->next = NULL;
}
// List all the vertex.
void Graph::listVertex() {
VPTR temp = V;
while(temp) {
cout <<temp->i <<" ";
temp = temp->next;
}
cout <<"\n";
}
// Client program
int main() {
Graph G;
G.addEdge(1, 2);
G.listVertex();
}
With the above code, you can expand to do DFS/BFS etc.