Reputation:
I'm trying to print a depth-first traversal. I have the following code which continues to give me a seg fault. It seems to be occurring when I try to print the last vertex in the graph. The first traversal I do starting at vertex 'A', works as it should. But when I try to do a depth-first print starting from D, I get the seg fault. Here is my source code:
Here is my original source code:
void wdigraph::depth_first(int u) const {
bool found = false;
vector<bool> visited; // create a boolean vector
for(int i =0; i < size; i++) // the size of the graph
visited.push_back(false); // to mark when a node has been visited
stack<int> depth_first; // used to hold vertices that have been visited
visited[u] = true; // mark as visited
cout << label[u]; // print first vertex
depth_first.push(u); // put first vertex on stack
while(!all_visited(visited)) { // continue until all vertices have been visited
found = false;
for(unsigned i = 0; i < visited.size() && !found; i++) {
if(adj_matrix[u][i] != 0 && !visited[i]) { // found next vertex
cout << "->" << label[i]; // print vertex
visited[i] = true; // mark vertex as visited
depth_first.push(i); // push vertx onto stack
found = true; // set found = true to end for loop
u = i;
}//endif
}//endfor
if(found == false) { // no available neighbors
u = depth_first.top(); // get top of stack
depth_first.pop(); // pop from stack
}//endif
}//endwhile
cout << '\n';
}
void wdigraph::print_graph() const {
cout << '\n';
cout << "No of Nodes = " << size << endl;
cout << "\nAdjacency Matrix\n" << endl;
cout << " |";
for(int i = 0; i < size; i++)
cout << " " << label[i];
cout << '\n';
cout << "--|";
for(int i = 0; i < size; i++)
cout << "---";
cout << '\n';
for(int i = 0; i < size; i++) {
cout << label[i] << " |";
for(int j = 0; j < size; j++) {
if(adj_matrix[i][j] != 0)
cout << " " << setw(2) << right << adj_matrix[i][j];
else
cout << " -";
}//endjfor
cout << '\n';
if(i != size-1)
cout << " |" << endl;
}//endifor
cout << '\n';
}
bool all_visited(vector<bool> &v) {
for(unsigned i = 0; i < v.size(); i++)
if(v[i] == false)
return false;
return true;
}
This is the header file and the constructor:
// definition of weighted digraph
#define NO_NODES 1 // default size for no of nodes in digraph
#define LINK_PROB 0.25 // prob of having direct link between nodes
#define MAX_WEIGHT 10 // max weight factor for links
class wdigraph {
public:
wdigraph ( int = NO_NODES ); // default constructor
~wdigraph ( ) { }; // destructor
int get_size ( ) const { return size; } // returns size of digraph
void depth_first ( int ) const;// traverses graph using depth-first search
void print_graph ( ) const; // prints adjacency matrix of digraph
private:
int size; // size of digraph
vector < char > label; // node labels
vector < vector < int > > adj_matrix; // adjacency matrix
};
// default class constructor
wdigraph :: wdigraph ( int n ) : size ( n )
{
// allocate dynamic memory
label = vector < char > ( size );
adj_matrix = vector < vector < int > > ( size );
for ( int i = 0; i < size; i++ )
adj_matrix [ i ] = vector < int > ( size );
// assign labels to each node
label [ 0 ] = 'A';
for ( int i = 1; i < size; i++ )
label [ i ] = label [ i - 1 ] + 1;
// determine weights for links between nodes randomly
// and build adjacency matrix
srand ( 1 );
for ( int i = 0; i < size; i++ ) {
adj_matrix [ i ] [ i ] = 0;
bool flag = false;
for ( int j = 0; j < size; j++ ) {
if ( j == i ) continue;
double r = ( double ) rand ( ) / RAND_MAX;
adj_matrix [ i ] [ j ] =
( r <= LINK_PROB ) ? rand ( ) % MAX_WEIGHT + 1 : 0;
if ( adj_matrix [ i ] [ j ] > 0 ) flag = true;
}
// if node is not connected to any other node, then
// connect this node to random node
if ( size > 1 && !flag ) {
int k; while ( ( k = rand ( ) % size ) == i ) ;
adj_matrix [ i ] [ k ] = rand ( ) % MAX_WEIGHT + 1;
}
}
}
Here is the main routine:
#define M 3 // print every M-th node's path when traversing
#define N2 5 // number of nodes in second graph
#define N3 20 // number of nodes in third graph
void proc_graph(wdigraph&); // function declaration
int main() {
// create three weighted digraphs
wdigraph graph1(NO_NODES);
wdigraph graph2(N2);
wdigraph graph3(N3);
//proc_graph(graph1); // print first graph
proc_graph(graph2); // print first graph
//proc_graph(graph3); // print first graph
return 0;
}
void proc_graph(wdigraph &g) {
cout << '\n';
cout << "A Weighted Digraph" << endl; // print header
cout << "__________________" << endl; // print header underline
g.print_graph(); // print graph
cout << "Paths by Depth-First Search" << endl;
for(int i = 0; i < g.get_size(); i += M)
g.depth_first(i);
}
This is the output that I am getting. The graph shows the weight of each edge. A '-' means there is no edge.
A Weighted Digraph
__________________
No of Nodes = 5
Adjacency Matrix
| A B C D E
--|---------------
A | - - - 6 -
|
B | - - 8 - -
|
C | 7 - - - -
|
D | 7 9 10 - 1
|
E | 4 - 10 - -
Paths by Depth-First Search
A->D->B->C->E
Segmentation fault (core dumped)
If I remove the u = i
code from the for loop, then my program works fine. Here is my output when I try to print the third graph. Notice, my traversal is not traveling correctly.
Upvotes: 5
Views: 5237
Reputation:
So I figured out my problem using the following algorithm. Hope this will help anyone having the same problem.
push current onto stack
mark as visited
print current
while (stack is not empty) {
current = stack top
of N neighbors of current, find first that hasnt been visited
if such neighbor exists
add to stack
mark as visited
print
if no neighbor exists
pop from stack
}
Upvotes: 3