I'm trying to loop through my adjacency list in my DFS search class, but its giving me this error: type 'AdjList' does not provide a subscript operator. I feel like it might be the way i saved adjList constructor for DFS but I'm not sure. I saw other solutions saw it has to be passed as a pointer so I changed AdjList list in the constructor to AdjList* list but that did not work. Here is my code:
main.cpp
AdjList::AdjList(){}
AdjList::AdjList(vector<Node> nodeVector){
nodeContainer = nodeVector;
}
void AdjList::makeAdjList(){
int temp;
for(int i = 0; i < nodeContainer.size(); i++){
connections = nodeContainer[i].getConnectionsVector();
for(int x = 0; x < connections.size(); x++){
innerList.push_back(nodeContainer[connections[x] - 1]);
}
adjList.push_back(innerList);
innerList.clear();
}
}
//other AdjList functions
int main(){
vector<Node> nodeContainer;
nodeContainer = load();
AdjList adjList(nodeContainer);
adjList.makeAdjList();
DFS search(nodeContainer, adjList);
search.iterative(6,3);
}
DFS.cpp
DFS::DFS(vector<Node> nodeVec, AdjList list){
nodeContainer = nodeVec;
adjList = list;
}
vector<Node> DFS::iterative(int src, int dest){
vector<Node> vectorPath;
list<Node>::iterator it;
int i = 6;
for(it = adjList[i].begin(); it != adjList[i].end(); it++){ //this is where the
//error is happening
cout << it->getNodeID() << " ";
}
return vectorPath;
}
AdjList.h
class AdjList{
private:
public:
list<Node> innerList;
vector<list<Node> > adjList;
vector<Node> nodeContainer;
vector<int> connections;
int temp;
AdjList();
AdjList(vector<Node> nodeVector);
void makeAdjList();
void displayAdjList();
};
When you say adjList[i], C++ looks for an operator[] in the type of adjList which is AdjList. As this type doesn't have such a member function you get the error message that it's missing.
Supply a
std::list<Node>& operator[](std::size_t i);
std::list<Node> const& operator[](std::size_t i) const;
and return adjList[i] in both.
Related
Can anybody explain me, how to do Breadth first search in the graph that uses vector of linked lists ?
My Graph header file:
#include <string>
#include <iostream>
#include <map>
#include <vector>
using namespace std;
struct vertex {
string code;
vertex* next;
};
struct AdjList {
vertex *head;
AdjList(vertex* Given) {
head = Given;
}
};
class Graph {
map<string, string> associations;
int nodeNum; //amount of nodes or size of the graph;
vector<AdjList> adjList;
public:
Graph(int NodeNum);
~Graph();
int singleSize(string codeName);
int getSize();// must destroy every prerequisite list connected to the node
vertex* generateVertex(string codeName);
int getIndexOfVertex(vertex* givenVertex); // will find the location of the vertex in the array
void addVertex(vertex* newVertex);
void addEdge(string codeName, string linkCodeName);
void printPrerequisites(vertex* ptr, int i);
bool deleteVertex(string codeName);
bool deleteEdge(string codeName, string linkCodeName);
bool elemExistsInGraph(string codeName);
void printPrereq(string codeName);
void printCourseTitle(string codeName);
void printGraph();
};
I am trying to print all connected nodes within the graph using the breadth first search. Here is my code for the breadth first search algorithm that does not work.
void Graph::printPrereq(string codeName) {
int adjListSize = this->adjList.size();
int index = getIndexOfVertex(generateVertex(codeName));
bool visited[this->adjList.size()];
for(int i = 0; i < adjListSize; i++) {
visited[i] = false;
}
list<int> queue;
visited[index] = true;
queue.push_back(index);
while(!queue.empty()) {
index = queue.front();
vertex* pointer = this->adjList[index].head;
cout << pointer->code;
queue.pop_front();
while(pointer != nullptr){
if(!visited[getIndexOfVertex(pointer)]) {
queue.push_back(getIndexOfVertex(pointer));
visited[getIndexOfVertex(pointer)] = true;
}
cout << pointer->code <<"->";
pointer = pointer->next;
}
cout << "Null" << endl;
}
}
This algorithm outputs nodes that are only within the linked list, but not the ones that are connected through the graph.
Can anybody help and solve this problem?
I was learning the dijkstra's algorithm and then in that there was the concept of priority queue with min_heap implementation where my priority_queue <Node,vector<Node>,comp> min_heap and the comp is a comparison struct;
struct Edge{
int src;
int dest;
int weight;
};
struct Node{
int vertex;
int weight;
};
class Graph{
public:
vector<vector<Edge>> adjList;
Graph(vector<Edge> &edges,int N){
adjList.resize(N);
for(auto &edge:edges){
adjList[edge.src].push_back(edge);
}
}
};
struct comp{
bool operator()(const Node &lhs,const Node &rhs) const{
return lhs.weight>rhs.weight;
}
};
void dij(Graph g,int source,int N){
priority_queue<Node,vector<Node>,comp> min_heap;
min_heap.push({source,0});
vector<int> dist(N,INT_MAX);
dist[source] = 0;
vector<bool> done(N,false);
done[0] = true;
while(!min_heap.empty()){
Node node = min_heap.top();
min_heap.pop();
int u = node.vertex;
for(auto i:g.adjList[u]){
int v = i.dest;
int weight = i.weight;
if(!done[u] && dist[u]+weight<dist[v]){
dist[v] = dist[u] + weight;
min_heap.push({v,dist[v]});
}
}
done[u] = true;
}
cout<<"The path from vertex "<<source<<" to "<<N<<" is "<<dist[N];
}
The code works fine and prints the minimum cost but I am not understanding the struct comp(); and how this works.
Trying to implement an adjacency matrix graph and practice OOP. I've been stuck on implementing the inserNode(string ) method.
My troubles are with accessing the private data fields. What am I completely missing?
Some of the errors:
Graph.cpp:30:26: error: unknown type name 'node'
graph[id] = new node;
^
Graph.cpp:35:10: error: use of undeclared identifier 'numnodes'
numnodes++;
Graph.cpp:34:19: error: expected ';' at end of declaration
graph[id]->nodename = name;
Graph.cpp:34:15: error: decomposition declaration '[id]' requires an initializer
graph.h
#include <iostream>
using namespace std;
class Graph {
public:
Graph();
int insertNode(string name);
private:
static const int vertices = 20;
int nodeCount;
struct node {
int nodeid; // node position in graph[]
string nodename; // username
};
// pointers to the graph nodes
node *graph[vertices];
// adjacency matrix for graph. True if edge is going from node i to j.
bool edges[vertices][vertices];
};
#endif
graph.cpp
#include "Graph.h"
Graph::Graph() {
for (int i = 0; i < vertices; i++) {
graph[i] = 0;
for (int j = 0; j < vertices; j++ )
edges[i][j] = 0;
}
}
/* create node and insert pointer in first available graph position. Returns id value, -1 if unsuccessful. */
int insertNode(string name) {
int id = 0;
while (id < vertices) {
if (graph[id] == NULL) {
graph[id] = new node;
if (!graph[id])
return -1;
graph[id]->nodeid = id;
graph[id]->nodename = name;
numnodes++;
return id;
}
id++;
}
return -1;
}
The insertNode you've defined is not the same way you declared in Graph. You've just made a free function called insertNode, which isn't a member of Graph and therefore can't access Graph. You need to define it like so:
int Graph::insertNode(string name)
{
}
Hello I have a question regarding the usage of typedef in C++. I am trying to create my own graph class where I can perform DFS and BFS. I have attached what I have for the class so far. But every time I try to compile I run into certain errors that I just do not know how to fix. I am sure the error has something to do with the variable vertexList that I use to hold all the vertices.
#include <iostream>
#include <stack>
class myGraph{
public:
typedef struct Vertex{
char label;
bool visited;
}Vertex;
myGraph(int);
void AddVertex(char);
void addEdge(int, int);
int adjUnvisited(int);
void displayVertex(int);
void dfs();
private:
Vertex* vertexList;
int** adjMatrix;
int size;
int vertices;
int count;
};
myGraph::myGraph(int size){
count = 0;
size = size;
vertices = size;
vertexList = new Vertex[vertices];
adjMatrix = new int*[size];
for(int i=0; i<size; i++){
adjMatrix[i] = new int[vertices];
}
for(int i=0; i<vertices; i++){
for(int j=0; j<vertices; j++){
adjMatrix[i][j] = 0;
}
}
}
void myGraph::AddVertex(char label){
Vertex* myVertex = new Vertex();
myVertex->label = label;
myVertex->visited = false;
vertexList[count++] = myVertex;
}
void myGraph::addEdge(int a, int b){
adjMatrix[a][b] = 1;
adjMatrix[b][a] = 1;
}
int myGraph::adjUnvisited(int index){
for(int i=0; i<vertices; i++){
if(adjMatrix[i][index]==1 && vertexList[i]->visited==false){
return i;
}
}
return -1;
}
void myGraph::displayVertex(int index){
std::cout << "Current vertex: " << vertexList[index]->label << std::endl;
}
void myGraph::dfs(){
std::stack<int> myStack;
int temp = 0;
vertexList[temp]->visited = true;
myStack.push(temp);
int unvisitedVertex;
while(!myStack.empty()){
unvisitedVertex = adjUnvisited[myStack.top()];
if(unvisitedVertex!=-1){
myStack.push(unvisitedVertex);
displayVertex(unvisitedVertex);
vertexList[unvisitedVertex]->visited = true;
}else{
myStack.pop();
}
}
}
The error message that I get is this:
no viable overloaded '=' vertexList[count++] = myVertex;
Along with a note:
candidate function (the implicit copy assignment
operator) not viable: no known conversion from 'struct Vertex *' to
'const myGraph::Vertex' for 1st argument; dereference the argument with *
struct Vertex{
And some other error messages which are (I'm sure these are very minor and I can figure them out):
member reference type 'struct Vertex' is not a
pointer; maybe you meant to use '.'?
if(adjMatrix[i][index]==1 && vertexList[i]->visited==false){
reference to non-static member function must be called
unvisitedVertex = adjUnvisited[myStack.top()];
Now I am not sure what exactly I am doing wrong and was wondering if someone here could help me out.
Thank you very much for all your help!
You've declared vertexList as a pointer-to-Vertex - which is fair enough, since it's going to be an array. But that means that each element of that array is a Vertex structure - yet you're accessing each array element as though it was a pointer.
Either:
Replace all the ->s with .s and do something different in AddVertex()
Declare vertexList as a Vertex ** (like adjMatrix)
I've a question to ask.
So, I have a structure call Node as shown below:
struct Node
{
int xKoor, yKoor;
Node *parent;
char nodeId;
float G;
float H;
float F;
Node(int x, int y, int id, Node * par)
{
xKoor = x;
yKoor = y;
nodeId = id;
parent = 0;
}
Node(int x, int y, char id)
{
xKoor = x;
yKoor = y;
nodeId = id;
}
};
And I have list that contains elements of this structure:
list<Node*> OPEN;
This list's size varies in time.
What I need to do is to find the Node object which has the minimum F value, then pop out that object from the list.
So, I tried to write a function as shown below:
void enKucukFliNodeBul(list<Node*> OPEN)
{
list<Node*>::iterator it = OPEN.begin();
for(it = OPEN.begin(); it != OPEN.end(); it++)
{
if(it._Ptr->_Myval->F < it._Ptr->_Next->_Myval->F)
{
}
}
}
But I'm stuck. I'm new to STL. How can I solve this?
My best regards...
You can use std::min_element with a suitable comparison function for this.
bool nodeComp(const Node* lhs, const Node* rhs) {
return lhs->F < rhs->F;
}
#include <algorithm> // for std::min_element
list<Node*>::iterator it = std::min_element(OPEN.begin(), OPEN.end(), nodeComp);
This assumes that list<Node*> is std::list<Node*>, in which case you should be aware that std::list itself is a linked list.
Other useful operations, based on your comments:
Remove a minimum value node from the list and delete it:
OPEN.erase(it);
delete *it; //
You may need to perform other operations, if your nodes depend on each other.
Sort the list:
OPEN.sort(nodeComp);
use std::min_element algirithm and overload Compare function
bool compareF(Node *lhs, Node *rhs)
{
return lhs->F < rhs->F;
}
if you are using C++03:
std::<Node*>::itertor ter = std::min_element(OPEN.begin(),OPEN.end(), compareF);
if you are using C++11:
auto iter = std::min_element(OPEN.begin(),OPEN.end(), compareF);
To sort the list, you can call OPEN.sort(compareF); to sort your list with compareF function
Try adding this:
bool compare_node_F(Node* n1, Node* n2)
{
return n1-> F< n2-> F;
}
#include <list>
#include <algorithm>
#include <cstdlib>
#include <iostream>
int main()
{
std::list<Node*> nodes;
for(int i= 100; i--;)
{
Node* n= new Node(42, 42, 42);
n-> F= i;
nodes.push_back(n);
}
std::list<Node*>::iterator min_element_iter= std::min_element(nodes.begin(), nodes.end(), compare_node_F);
std::cout<< "Min F: "<< (*min_element_iter)-> F<< '\n';
for(std::list<Node*>::iterator d= nodes.begin(); d!= nodes.end(); ++ d)
delete *d;
}