class graph
{
int v;
list<int> *adj;
void dfsutil(int v,bool visited []);
public:
graph(int v)
{
this->v=v;
//adj = new list<int>[v];
adj = (list<int> *)malloc(v*sizeof(list<int>));
}
void addedge(int v,int w);
void dfs(int v);
};
void graph::addedge(int v,int w)
{
adj[v].push_back(w);
}
void graph::dfsutil(int v,bool visited[])
{
list<int>::iterator i;
cout<<v<<" ";
visited[v]=true;
for(i=adj[v].begin();i!=adj[v].end();i++)
{
if(!visited[*i])
dfsutil(*i,visited);
}
}
void graph::dfs(int v)
{
int i=0;
bool visited[this->v];
for(i=0;i<this->v;i++)
visited[i]=false;
dfsutil(v,visited);
for(i=0;i<v;i++)//this loop is required if there are multiple component of the graph
if(!visited[i])
dfsutil(i,visited);
}
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 Depth First Traversal (starting from vertex 2) \n";
g.dfs(2);
return 0;
}
in the above code if try to allocate space for list *adj using malloc as written above,it does not work fine whereas if we use new,it works fine as its written in commented part above,i cant figure out why
You did not create an array of std::list objects when you used malloc. All malloc does is allocate memory from the heap -- no objects are created. Thus attempting to use your std::list's as if they are created correctly will result in undefined behavior.
You should use a container such as std::vector to store your list objects:
#include <vector>
#include <list>
class graph
{
int v;
std::vector<std::list<int>> adj;
void dfsutil(int v,bool visited []);
public:
graph(int num) : v(num), adj(num) {}
void addedge(int v,int w);
void dfs(int v);
};
Note there is no need to allocate memory. The rest of your code should stay the same, since vector has an overloaded operator [] to access the items.
Related
using namespace std;
bool *marked;
//graph API
class Digraph
{
int v;
vector<int>* adj;
int e;
public:
Digraph(int V)
{
e=0;
v=V;
adj=new vector<int>[v];
}
void addEdge(int v,int w)
{
adj[v].push_back(w);
e++;
}
int V()
{
return v;
}
vector<int> adjacent(int i)
{
return adj[i];
}
};
//API ends
//this is the problem
void dfs(Digraph g,int s)
{
marked[s]=true;
for(int w:g.adjacent(s))
{
if(!marked[w])
dfs(g,w);
}
}
The Dfs here would run perfectly when traversing nodes but when returning it would stop at one node before the last and my program halts.I compiled it on codeblocks ide.
For ex
consider a graph going 1->2->3->4->0->1
when traversing its fine but when returning will stop at vertex 3
Actually i was implementing Cycles in a graph and topological sorts too. but none of them worked, and i have no idea why.
This is the representation of an adjacency list.When i try to print the graph the loop does not terminate and keeps repeating weird values again and again.What is wrong in the loops
#include<iostream>
#include<list>
using namespace std;
class Graph{
int V;
list<int> *l;
public:
Graph(int v){
V=v;
l=new list<int>[V];//Array of linked lists
}
void addEdge(int u,int v, bool bidirec=true){
l[u].push_back(v);
if(bidirec){//condition for bidirectional graph
l[v].push_back(u);
}
}
void printAdjList(){
for(int i=0;i<V;i++){
cout<<i<<"-->";
for(int vertex:l[i]){//For each loop
cout<<vertex<<",";
}
cout<<endl;
}
}
};
int main(){
Graph g(5);//graph with 5 vertices
g.addEdge(0,1);//adding edges
g.addEdge(0,4);
g.addEdge(4,3);
g.addEdge(1,4);
g.addEdge(1,2);
g.addEdge(2,3);
g.printAdjList();
return 0;
}
I'm doing some work on data structures, just to learn. Right now I have an admittedly very basic graph data structure.
I can create the graph with a predefined size, and then add edges to/from each vertex (un-directed). Here is the code so far:
graph.h
#pragma once
#include "stdafx.h"
#include <vector>
#include <iostream>
#include <algorithm>
class Graph {
int vertices; // num of vertices in graph
std::vector<int> *adjList;
public:
Graph(int vertices);
void addEdge(int v, int w);
void printGraph();
};
Graph::Graph(int vertices) {
this->vertices = vertices;
adjList = new std::vector<int>[vertices];
}
void Graph::addEdge(int v, int w) {
adjList[v].push_back(w);
}
void Graph::printGraph() {
for (int i = 0; i < adjList->size(); ++i) {
}
}
graph.cpp
#include "stdafx.h"
#include "graph.h"
int main()
{
Graph graph(4);
graph.addEdge(0, 1); //counter starts at 0
graph.addEdge(0, 2);
graph.addEdge(2, 1);
graph.addEdge(2, 3);
return 0;
}
This works fairly well, however I would also like to add nodes after the graph object has already been created. I really can't figure out how to do this.
Any sort of guidance towards this (as well as general improvements to the code) will be greatly appreciated.
Use a vector to store your adjacency list and resize it when required:
std::vector<std::vector<int>> adjList;
Don't allocate it with new, don't delete it, use standard containers!
I'm trying to detect and print a cycle in an undirected path, starting from a given vertex. So far, the path is recorded in a vector. The code seems to work, but there's one more vertex reported than it should be.
For the given example, one expected path would be: -1,6,0,5,3 which also put out: -1,6,0,5,3,2 but there's one more vertex than expected.
Maybe somebody has an idea how this can be fixed.
Thanks in advance!
#include <vector>
#include <iostream>
class Vertex
{
public:
Vertex() {};
Vertex(int x, int y, bool visited) : _x(x), _y(y){}
int _x;
int _y;
};
class Edge
{
public:
Edge(Vertex* from, Vertex* to): _from(from), _to(to){}
Vertex* _from;
Vertex* _to;
};
class MyGraph
{
public:
void addVertex(int x, int y, bool visited);
void addEdge(Vertex* vp1, Vertex* vp2);
bool dfs(int v, int p);
std::vector<std::vector<int>> g;
bool* visited;
std::vector<Edge> edges;
std::vector<Vertex> vertices;
std::vector<int>path;
};
void MyGraph::addVertex(int x, int y, bool visited)
{
Vertex v = Vertex(x, y, visited);
this->vertices.push_back(v);
}
void MyGraph::addEdge(Vertex* vp1, Vertex* vp2)
{
Edge e = Edge(vp1, vp2);
this->edges.push_back(e);
}
bool MyGraph::dfs(int v, int p)
{
visited[v] = true;
this->path.push_back(p);
for (int i = 0; i < (int)g[v].size(); i++)
{
if (!visited[g[v][i]])
{
dfs(g[v][i], v);
return true;
}
if (g[v][i] != p)
{
return true;
}
}
this->path.pop_back();
return false;
}
int main(int argc, char** argv)
{
MyGraph mg;
mg.addVertex(3, 0, false);
mg.addVertex(0, 1, false);
mg.addVertex(2, 1, false);
mg.addVertex(0, 2, false);
mg.addVertex(1, 2, false);
mg.addVertex(3, 2, false);
mg.addVertex(0, 0, false);
mg.g.resize(mg.vertices.size());
mg.g[0].push_back(5);
mg.g[0].push_back(6);
mg.g[1].push_back(2);
mg.g[1].push_back(3);
mg.g[1].push_back(6);
mg.g[2].push_back(1);
mg.g[3].push_back(2);
mg.g[3].push_back(4);
mg.g[3].push_back(5);
mg.g[3].push_back(6);
mg.g[4].push_back(3);
mg.g[4].push_back(5);
mg.g[5].push_back(0);
mg.g[5].push_back(3);
mg.g[5].push_back(4);
mg.g[6].push_back(0);
mg.g[6].push_back(1);
mg.g[6].push_back(3);
// expected path: 6,0,5,3
mg.visited = new bool[mg.vertices.size()]{false};
std::vector<int> pppath;
std::cout << mg.dfs(6, -1) << std::endl;
for (auto n : mg.path)
{
std::cout << n << ",";
}
return 0;
}
Thanks for your input. The problem has been solved. The push_back has to happen a line later in the for loop. Nonetheless, the code has the problem that the adjacency list has to be created on a certain order to avoid jumping back directly to the starting point.
I am looking for solution to pick a number randomly from graph using c++.
For example I have a graph that add edge (one or more) between two vertices, how can I pick a number randomly?
some of code :
#include <iostream>
#include <list>
#include <queue>
using namespace std;
// Graph class represents a undirected graph using adjacency list representation
class Graph
{
private:
int V; // # of vertices
list<int> *adj; // Pointer to an array containing adjacency lists
public:
Graph(int V) // Constructor
{
this->V = V;
adj = new list<int>[V];
}
void addEdge(int v, int w); // function to add an edge to graph
void print(int v, int w); //function to display
};
void Graph::addEdge(int v, int w)
{
adj[v].push_front(w); // Add w to v’s list.
adj[w].push_front(v); // Add v to w’s list.
print(v, w);
}
void Graph::print(int v, int w) {
cout << v << " - " << w << endl;}
In the main:
Graph g(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 3);
Sample output:
0 - 1 0 - 2 1 - 3
Use math lib. Rand function. Select random num and select (0 to number of edges-1) from list of edges, then select another random number and select that vertex of the edge, 0 or 1 (bottom/top vertex of edge)
#include <stdlib.h>
#include <iostream>
#include <list>
#include <queue>
using namespace std;
// Graph class represents a undirected graph using adjacency list representation
class Graph
{
private:
int V; // # of vertices
list<int> *adj; // Pointer to an array containing adjacency lists
public:
Graph(int V) // Constructor
{
this->V = V;
adj = new list<int>[V];
}
void addEdge(int v, int w); // function to add an edge to graph
void print(int v, int w); //function to display
};
void Graph::addEdge(int v, int w)
{
adj[v].push_front(w); // Add w to v’s list.
adj[w].push_front(v); // Add v to w’s list.
print(v, w);
}
int Graph::getRandomVertexFromEdge()
{
int list_size_divided_by_2 = adj.size() / 2;
int rEdge = (rand() % list_size_divided_by_2);
int rVW = (rand() % 1);
int ret = adj[(rEdge + rVW)];
//this will return a random vertex from a random edge;
print(rEdge,rVW);
return ret;
}
void Graph::print(int v, int w) {
cout << v << " - " << w << endl;}