Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I want to do some operations on a graph. Before I start operations I have tried to construct the graph. But I'm not sure if I did correctly. Can you say if I'm in the right direction?
The input will be like this :
A
B
C
A B 1
A C 2
B C 3
I have put nodes into a char vector like this :
vector<char> nodes;
And I have put edges into a Edge vector like this :
class Edge
{
private :
int length;
char node1;
char node2;
public :
Edge(int l, char n1, char n2);
};
You seem to be on the way to a valid solution.
To my knowledge, there are two canonical approached to implementing graph data structures.
The first is with an edge list, which seems to be the approach you have chosen. The graph structure is represented by a list of edges with optional weights. Note, you may want to add more to this to make for a more efficient structure, depending on the uses for your graph. For example, if you need to find a list of all neighbors of a node quickly, it may be better to store an edge list for each incident node.
A second approach would be to represent the graph as a matrix-like structure where the entry (i,j) is either a boolean representing whether there is an edge from node i to node j.
It is not the efficient way you can implement a graph.
Vertexes and Edges are different entities, so they need to be represented by different data structures.
Like 2 classes : class Vertex and class Edge.
Also concept of cyclic dependency must be used. For further details, please check this site:
http://badboys.7p.com/notes/Graph%20-%20Linked%20Implementation%20(C++).htm
First you need a simple Node class. The node class usually contains a linked list (use a list!) of child nodes. In your case you are using a graph with edges so your nodes should contain linked lists of edges that connect to children. Also, I'm not sure why you are using char to reference your nodes, you should be using a Node class with Node references.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
Given the EleList class how do I go about writing the implementation of the Insert() function?
I've never really used pointers so this simple problem really has me stumped, I would appreciate a link to relevant learning material if possible.
class EleList
{
public:
EleList( char cData )
: m_cData(cData)
, m_Left(0)
, m_Right(0)
{
}
static void Insert( EleList* InsertEle,
EleList* InsertPos);
private:
char m_cData;
EleList* m_Left;
EleList* m_Right;
};
// Insert() function
void EleList::Insert( EleList* InsertEle,
EleList* InsertPos)
{
}
Pointers seem a bit tricky in the beginning. I strongly recommend you to draw in paper the algorithm you want to implement when it involves data structures and pointers, before doing any code. A linked list is a good way to start to learn them.
Into the implementation you can take several approaches, because you have to consider different cases:
Inserting at the beginning of a list or in an empty list: we create the node and swap the left pointer with the head of the list.
Inserting in the middle of a list: we iterate the list with an auxiliary pointer until the desired position, we create the new node and redirect the necessary pointers (the ones of the new node and the ones from the neighbour nodes).
Inserting at the end of the list: we iterate until the last element, create the new node and attach them to each other with the pointers.
You can try to implement one and from there try another. If you are learning, it doesn't have to be perfect, it has to make you understand how pointers and data structures work.
I'm sure you will find this link useful, it's very complete and has an extensive example in code.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Ive got an exercise due to tommorow and Ive got completely no idea how to do it, even though I know how to add to list, delete an element from list ( last or first ), or display a list, maybe its because I only know how to do it with one variable in struct.
sorry if my translation is not the best but Im translating the exercise from polish.
1.We have a structure
struct point {
double x, y;
};
Create a function that creats lists of consisting of n points
Then after it
Using the list created in previous exercise, create a function that prints on the screen coordinates of points lying inside the given circle. Pointer for the beginning of the list and defining values transfer as function parameters.
I was trying to do it alone but as of now Ive got completely no idea how to approach this. I think as for the first one, I should create a list, head and tail and next,then constructor that sets head and tail to NULL, then function that adds elements to list, then in main ask user for the 'n' value and create for loop with that function.
After that, Ive got completely no idea what to do next. I may have been wrong even until now.
Sorry if I waste your time reading this, I just hope someone can help me and explain me what to do.
Sorry if its also not the place to ask for that kind of help, Im kinda new to all of this.
You should separate the concept of data from the links.
struct Node
{
Point data;
Node * p_previous;
Node * p_next;
};
Later on you may want to make the list into a template so that you can pass any type for the data field.
To get the coordinates from a Node:
Point coordinate = p_node->data;
double x_ordinate = coordinate.x;
double y_ordinate = coordinate.y;
Off-topic: screen coordinates should be integers, not floating point. Usually, pixels are hole element, I haven't heard of real partial pixels.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I have a text file that is similar to:
person: head, body
head: eyes, nose, ears, mouth
body: arm, leg
arm: elbow, hand
leg: thigh, knee, foot
I'm trying to represent this in either an adjacency list or a directed graph. What's the best way to do this? I can't figure out the best data structure or how to represent this in C++.
I've tried using a struct with values for the key (person, head, etc) and it's parent index, and it's children as a vector:
struct Node
{
string key;
int parentIndex;
vector<string> children;
};
But this doesn't seem efficient. Any ideas?
Maybe this would be better?
struct {
string key;
Node* parent;
vector<Node> children;
};
There are several questions that remain unanswered by your data sample: is there always one single point of entry (ex: person) ? is it always a top down decomposition (i.e. each element has max one parent) ? do the elements always come in the right odrer: first the top, then the down ?
If the answers to all three questions are yes, then your proposed structure is suitable:
It's efficient enough, if always start exploration from the top.
It'll be time consuming to find a specific node, as you've to traverse the whole structure.
There are still several points to fix:
It'll be tricky to copy a node (because of the pointer to parents that must be changed for the copied node, as well as for its childern and children's children.
adding elements to an array might invalidate parent poitners of all the chilren and children's children.
As you see, the optimal data structure depends not only on the content, but also on how you're going to use it.
There are plenty of iother approaches to do it, balancing performance aspects in a different manner. For example :
class mygraph {
struct node { // nodes that you read:
string name;
int id; // index of the node in the nodes vector
vector<int> in; // parent(s) that can lead to this node
vector<int> out; // children you can go to
};
vector<node> nodes; // all the nodes in arbitrary sequential order
map<string, int> dict; // map converting the names into ids (redundant and optional, useful for efficien search by name);
public:
// members to populate the structure and to acces the nodes cleanly.
};
Advantages:
find any node by id is extremely fast, as it's only indexing an array.
you don't need to worry about copy of structure as there are no pointers.
due to in/out vectors, you can quickly move forward or backward from whatever node you want.
redundant map (i.e. index and name) accelerates searching nodes by name
Inconvenience: there's some overhead when populating the structure: you need to convert every name into an id by verifying the name in the map and if absent create a new node in the nodes vector and insert name+new id in the map.
Every "word" needs its own node. So, your second struct is closer. But, just be sure that the container type for children can grow dynamically after creating the node and contains pointers to the child nodes.
For two reasons:
(1) Suppose we added a line at the bottom of your data: arm: wrist. It would need to be appended to children after the arm node had been created.
(2) Currently, your data file is well ordered. But, what if we randomized the order of your data lines? Would that still work? Most directed graph programs handle that just fine
As you parse a line left-to-right, get the word. Search all known nodes, looking for a match. After the first line has been parsed, you have three nodes: person, head, body. head and body are in the children of person [and their parent fields will both point to person], but their child lists are [currently] empty. person will be the root node.
If you find a match, which you would on the second line for head, use the existing head node, and fill in the children. With no match, create the node.
If the search fails and you have to create a new node, you may not have a place in the tree you're building to attach it to. In that case, add it to a "hold" list [which is also part of the search], until more nodes come in and you can attach the hold items as children in which case you remove them from the hold list.
You may have to update the root node. With the sample data, suppose we added household: person dog at the bottom. The root node would need to be adjusted accordingly. We'd also need a dog: line. If we don't have it at the end, that's an undefined value and would need to be flagged. Your node definition will need a defined bool to be able to flag this.
At the end, anything still in the hold list is extraneous data. For example, if we had a zebra: line, there's no reference to it [and its parent will be null], and that will also need to be flagged.
When linking things in, a given node can only be referenced once. So, if we add household: arm, this will conflict because arm is already a child of body. Detect this by parent already being non-null
I am learning C++ and I appreciate your support by answering my question to help me to understand fundamental concepts. I am sure I need to learn many stuff, but I need a some advice to help me to find the right way.
The problem I have is explained in below.
I want to implement a class to create a graph in C++. As I noticed, I can use matrices, but I am not interested in matrices as you can see later.
The graph is undirected and weighted. The graph is a vector of nodes and I use the standard library vector.
Each node(vertex) of the graph has below parameters and some neighbors.
node_index, node_degree, X, Y , Z.
The neighbors are nodes too and I can define a vector of nodes for them.
However, there are 3 reasons that I don't like to create a vector of nodes.
First,I don't need the Y,Z from a neighbor. I also need weight between this node and each of its neighbors.
Second, I need to calculate the node_degree, X for each node separately, and if I have duplicate nodes as neighbors, I need to update them manually that is extra work.
Third, the graph would be be large and I don't want to waste the valuable memory for useless information.
Having said that, I was thinking of having a base class that later I can derive the Node class and Neighbor class from it. Then for neighbors I keep a vector of pointers to beginning of each neighbor.
I don't know how, but I think I can cast that pointer to base class and by using it I can retrieve the information that I need from neighbor nodes.
In another words, I am trying to keep pointers to neighbors and when I update the neighbors parameters, I access to latest information of the nodes directly using pointers.
Would you please give a link to related topics that I should learn to implement it?
Please let me know if this is a very bad idea (by explaining the problems) and what is the better or best way to do this.
I advise you to use a Link structure, to represent an edge in the graph:
struct Link
{
Node *N;
float weight;
}
Then each Node can contain
vector<Link> neighbors;
This way there is no duplication of Nodes. There is a duplication of weights, since if Node A has a Link pointing to Node B, then Node B has a Link with the same weight pointing to Node A. If that duplication of weight is a problem (e.g. if the graph is so big that storage of the weights is expensive, or if weights are often updated), then you can make Link bidirectional (two Node* and one weight) and give each Node
vector<*Link>
The code will be slightly more complicated in that case, but it is the price of efficiency.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I am writing a simulation in c++ with a lot of little entities indexed by an integer, each having relationships of various types with one another. I have a basic structure storing the data about the relationship, and the relationships are unidirectional (A can be friends with B but B doesn't necessarily have any relationship with A).
So I have a lot of data that has the form (integer index, integer index, data...)
I will very often need to start with an entity (index) and find all of the relationships it has with others (so all triples with the first entry equal to some index).
I also will sometimes need to remove entities from the simulation and destroy all relationships that reference them (remove all triples with either the first or second entry equal to a given integer).
On one extreme, I can store everything in arbitrary order and search through it every time to construct any of the lists I need to get out of it (the lists I refer to in #1 and #2 above). This requires the least amount of data, but will also be very slow. Another extreme is where I keep track of multiple indexing structures that allow me to do the two operations I described above more quickly but that take up some memory. It's hard to compactly describe what I mean, but you could imagine a list of lists that allow you to quickly answer the question "what are all the relationships that have 47 as their first entry in the triple."
I don't know anything about data structures, but I imagine this must be a problem people have encountered and thought about before. Are there any C++ libraries with data structures that would automatically keep track of this type of indexing information or that are relevant to what I'm describing? Thanks!
I'd do something like this:
class Entity;
class Relationship // usually called Edge
{
Entity *from;
Entity *to;
// other data
};
class Entity // usually called Node
{
list<Relationship*> incoming;
list<Relationship*> outgoing;
};
vector<Entity*> roster;
You might want to wrap roster in some sort of EntityHandler class, to manage all of those pointers.
For #1, look up an Entity in the roster by its number (e.g. roster[5]), and that Entity's outgoing is what you want -- you can do a shallow copy (of the pointers), or a deep copy (of the Relationships).
For #2, look up the Entity and iterate over both of its Relationship lists; for each Relationship, remove the corresponding pointer from the list in the Entity at the other end, then delete the Relationship. Then delete the Entity. And don't forget to set the pointer in the roster to NULL.
Wikipedia has a good section on how to implement graphs, even has time and storage complexity.
There three main types are Incidence matrix adjacency matrix's and adjacency lists. Genrally speaking:
Incidence matrix's use a node*edge sized matrix and are best for hyper-graphs, graphs with edges/connections of to more than one node and multi-graphs, graphs witch allow more than one connection between two nodes. However the more edges, the more space.
adjacency lists are most efficient if they is lots of resizing, as data is non continuous, and sparse graphs, as they only allocate space for links that are there, but use pointers which take up more space. Adjacency lists are probably the easiest to implement for directed graphs)
lastly is the adjacency matrix, which stores a node*node matrix to check if two nodes are connected, for example if [1][3] is true the 1st node is connected to the third.
https://en.wikipedia.org/wiki/Graph_(data_structure) has good descriptions on their implementations, just watch out though, they say they is an 'incidence list', but it is just a link to an adjacency list implementation