Somebody can explain me this struct? - c++

I'm working on a Graph Theory Algorithm. I know what is a graph and what is an edge etc. I have this first part of this script in c++ where it declares some variables and some struct, and after it defines a function that adds an edge.
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int M = 500;
struct struct_edge
{
int v;
struct_edge * n;
};
typedef struct_edge * edge;
struct_edge pool[M * M * 2];
edge top = pool, adj[M];
int V, E, match[M], qh, qt, q[M], father[M], base[M];
bool inq[M], inb[M], ed[M][M];
void add_edge(int u, int v)
{
top->v = v, top->n = adj[u], adj[u] = top++;
top->v = u, top->n = adj[v], adj[v] = top++;
}
If this isn't enough I'll put an other part of the script.
I have some problem to understand why the struct_edge has a pointer to an other struct_edge (it's an edge not a node!). And I have some serious problem to understand this declaration:
edge top = pool, adj[M];
top is a pointer to a struct_edge and it has an array of struct and an array of int at the interior?!?
For a full code you can see this link
http://codeforces.com/blog/entry/49402

To answer your first problem, the graph is stored as an adjacency list format. Each node has an associated linked list of edges (struct_edge), each of which has an index (int v;) to the node at the end of the edge, and a pointer to the next edge (struct_edge* n;). The index is to the adj[M] array, which stores the M nodes that make up the graph.
Second problem, pool is a statically declared array of struct_edge, and the OP uses this to make a stack allocator, i.e. the new nodes are allocated by incrementing top, which is a pointer to the top of the stack. top is initialized to pool which is the base of the stack (start of the array).
EDIT: A diagram of the pointer arrangement for the wikimedia graph you linked:
(Note the indices start from 0 instead of 1, so Node 1 in the graph diagram corresponds to v = 0 in the code)

Related

C++ Creating Array of Pointers to Nodes in Directed Graph

I'm trying to create a directed graph represented by an array of pointers to nodes, but I'm struggling to add nodes into each index of the graph. Here is what I have:
struct Node {
int index;
list<Node*> outgoingNodes;
};
struct Graph {
Node* nodePointers; // Array of pointers to nodes in graph
int N; // Number of nodes in graph
};
Here is how I am creating the graph:
Graph* graph = new Graph();
graph->N = 7;
graph->nodePointers = new Node[graph->N];
I then try to add a node into index 0 in the graph in the following way, but I get an error that "operand types are 'Node' and 'Node*'":
Node* a = new Node();
a->index = 0;
graph->nodePointers[0] = a;
Without changing either of my structs, how could I correctly add a node into an index in my graph's array of node pointers?
Thanks for any help!
Node* nodePointers is a pointer to an array of Nodes. If you want an array of Node pointers, you need to declare it as Node** nodePointers, and allocate the array with new Node*[graph->N]:
struct Graph {
Node** nodePointers; // Array of pointers to nodes in graph
int N; // Number of nodes in graph
};
int main() {
Graph* graph = new Graph();
graph->N = 7;
graph->nodePointers = new Node*[graph->N];
...
}
First:
struct Node {
int index;
list<Node*> outgoingNodes;
};
Although correct, it is inefficient for no apparent reason. Almost always prefer a vector over a list. It is as easy to work with, but takes less memory and works faster on almost any conceivable use case:
struct Node {
int index;
std::vector<Node*> outgoingNodes;
};
Next, the code:
struct Graph {
Node* nodePointers; // Array of pointers to nodes in graph
int N; // Number of nodes in graph
};
Holds a block of Node objects, not pointers to nodes. The best thing is to use a vector of pointers:
struct Graph {
std::vector<std::unique_ptr<Node>> nodePointers; // pointers to nodes in graph
};
This way deallocation and memory management will be automatic.
Then your usage example becomes:
// are you sure graph has to be on the heap?
auto graph = std:: make_unique<Graph>();
graph->nodePointers.resize(7);
I then you can add a node into index 0 in the graph in the following way:
graph->nodePointers[0] = std::make_unique<Node>();
graph->nodePointers[0]->index = 0;
This was the better way to do it, but if you insist on:
Without changing either of my structs, how could I correctly add a
node into an index in my graph's array of node pointers?
Then you should note that "graph's array" is not made of pointers, but of nodes. So adding nodes is done differently:
// you can still allocate the graph on the heap, but the following way is safer
Graph graph;
graph.N = 7;
graph.nodePointers = new Node[graph.N];
But now nodePointers is a misnomer, because it should be named nodes (not pointers).
Then add a node into index 0 in the graph in the following way (by this point it is already constructed):
graph->nodePointers[0].index = 0;
And adding an edge looks lije:
graph->nodePointers[0].outgoingNodes.push_back(&graph->nodePointets[2]);
At line graph->nodePointers[0] = a; change this to graph->nodePointers[0] = *a; It will work.
Now let me explain you, Suppose you want an array of int then you can declare it as int x[10] or int *x=new int(10). What it shows in second case that x is an pointer which points to int object not to int pointer. I hope you got your solution.

Represent and traverse a n-ary tree as a vector

I've implemented a n-ary tree ( to be more specific, a trie ) and I was wondering if there's a method to represent and traverse it as a vector. With a binary tree that would be trivial ( see this question ) but I don't seem to find a way to perform this with a n-ary tree.
My final goal would be storing the vector represented tree to a file, mmap it and perform fast lookups without having it effectively loaded into memory.
An efficient approach to store a trie on disk ad using it with a mmap-ped pointer instead of allocating its inner structures would be great too.
Thanks.
If you have a tree where every node n has exactly k children, then you can proceed by placing the children of node n at positions k*n+m in the array, where m is between 0 and k-1. This will also work if every node has k or less children, but it will use a lot more memory than required if a lot of nodes have fewer than k children. The only other way I know of to store a tree as an array where nodes have different number of children is to store an auxillary array,, where for each node you store the offset into the original array to find that node's children and then you can either also store the number of children for each node or simply look up the offset for the next node's children to figure out how many children there are for the node.
Any graph structure can be represented as a flat array of nodes (in fact, that's how computer memory works). You just need to use indices instead of pointers, because pointers are invalidated when the vector grows or when the structure is mmap'd.
Here's a three-way tree as a flat vector:
struct Node {
Node(int data) : payload(data)
{
for (int i = 0; i < 3; i++) {
child[i] = (size_t)(-1); // invalid
}
}
int payload;
size_t child[3];
};
typedef std::vector<Node> Tree;
void add_node(Tree &t, size_t parent, int child_index, int payload)
{
t.push_back(Node(payload));
t[parent].child[child_index] = t.size() - 1;
}
You'll need separate logic to insert the root node since it doesn't have a parent. Also if you want a version where the mmap'd files can be used cross-platform, you'd better use fixed-size index types rather than the platform-specific int and size_t.
Traversal code is the same as with a pointer structure, except that
next = node->child[1]
becomes
t[t[node_idx].child[1]]
etc. i.e. each lookup of a node passes through the Tree object.
Assuming you know the No of node of the tree
you could change the size of adj vector to your suitable value
code->
#include<iostream>
#include<vector>
using namespace std;
vector<int> adj[100000000];
void dfs(int);
int main()
{
int i,n,root,par;
cin>>n;
//Input line contains n space separated integers.
// The ith integer represents the immediate ancestor of the ith node
// Node having 0 as parent node is the Root Node
i=1;
while(i<=n)
{
cin>>par;
if(par==0)
{
root=i;
}
else
{
adj[par].push_back(i);
}
i++;
}
//traversal of the Tree(Inorder traversal)
dfs(root);
}
void dfs(int at)
{
vector<int>::iterator it;
it=adj[at].begin();
cout<<*it<<" ";
while(it!=adj[at].end())
{
dfs((*it));
it++;
}
return;
}
Hoping this might helps

Graphs using Adjacency List in c++

I am trying to implement a graph in C++. I am representing a node in graph using a structure which contains two variables - a) an integer to contain some information about the node. b) a list to contain index of other vertex which are connected to it. Following is the code.
// Graphs using adjacency list
#include <iostream>
#include <list>
#include <cstdlib>
using namespace std;
// structure to represent a vertex(node) in a graph
typedef struct vertex{
int info;
list<int> adj; // adjacency list of edges contains the indexes to vertex
} *vPtr;
int main(){
vPtr node = (vPtr)malloc(sizeof(struct vertex));
node->info = 34; // some arbitrary value
(node->adj).push_back(2); // trying to insert a value in the list
return 0;
}
The code is compiling fine but I am getting a run time error while I am pushing back an element in the list. Is there any problem in my structure. I am using code blocks and GNU GCC, C++ 98 compiler to compile my code.
malloc is a C function - it shouldn't be used with C++ objects, which is very well explained here (short answer: in C++, when you are not dealing with POD types, std::list in your case, you must call the object's constructor to have the actual object ready for use, and malloc() does not do that).
You should used new instead. While malloc only allocates a block of memory of size vertex, new does that and also initializes std::list aswell by calling it's constructor (interesting to point out that when you call delete(), you are calling your object's desctructor aswell).
Here is a piece of code that works for your case, although I suggest you to start using more C++ features within C++ projects:
#include <iostream>
#include <list>
#include <cstdlib>
#include <new>
using namespace std;
// structure to represent a vertex(node) in a graph
typedef struct vertex{
int info;
list<int> adj; // adjacency list of edges contains the indexes to vertex
} *vPtr;
int main(){
cout << "allocating memory for our vertex struct... \n";
vPtr node = new vertex();
node->info = 34; // some arbitrary value
(node->adj).push_back(2); // trying to insert a value in the list
cout << "cleaning allocated memory... \n";
delete(node);
return 0;
}
Couple of things.
Because you are using malloc no constructor is ever called, and as
such the non primitive member adj is never constructed and is
NULL.
You are leaking memory since you never free/delete any of your dynamically allocated memory.
If you are using C++ why are you using malloc instead of new and delete?
You don't have to say struct vertex in the sizeof for C++.
To fix it you could do:
vPtr node = new struct vertex(); // also change to delete instead of free
or
// use current malloc line, change adj to be a pointer to a list and new it
// but this will cause additional problems for you since you really need to use a constructor for STL::list
node->adj = new list<int>;
Bottom line you really shouldn't be using malloc here.
This is UpAndAdam's answer, written completely.
// Graphs using adjacency list
//
#include <iostream>
#include <list>
#include <cstdlib>
using namespace std;
// structure to represent a vertex(node) in a graph
typedef struct vertex{
int info;
list<int> *adj; // adjacency list of edges contains the indexes to vertex
} *vPtr;
int main(){
vPtr node = (vPtr)malloc(sizeof(struct vertex));
node->adj = new list<int>;
node->info = 34; // some arbitrary value
(node->adj)->push_back(2); // trying to insert a value in the list
return 0;
}

custom alignment options for an efficient quad edge implementation

I'm fairly new to the D2 programming language. I need to implement a quad edge data structure. This is an adjacency data structure for effective graph embeddings and their duals.
From previous experience with C, I started with the following implementation:
struct edge(T) {
edge* next;
T* data;
uint position;
}
alias edge[4] qedge;
edge* new_edge() {
qedge* q = new qedge; // does not compile, just analogous
// initialize the four edges (q[i].position = i)
return cast (edge*) q;
}
That works fine, but this position field is bugging me - it is just wasting space there.
Is there a way to align to a (8 * ${machine word size}) boundary when allocating the memory for the qedge array (then I will not need the additional position field, because the information at which position an edge is in the qedge array will be encoded into the edge address)?
I'm aiming at an efficient and cute implementation (that's why I've chosen D), so any other suggestions are welcome.
EDIT: Here is a piece of code to make the thing more clear http://dpaste.dzfl.pl/e26baaad:
module qedge;
class edge(T) {
edge next;
T* data;
}
alias edge!int iedge;
alias iedge[4] qedge;
import std.stdio;
import std.c.stdlib;
void main() {
writeln(iedge.sizeof); // 8
writeln(qedge.sizeof); // 32
// need something for the next line,
// which always returns an address, divisible by 32
qedge* q = cast (qedge*) malloc(qedge.sizeof);
writeln(q); // ex. 0x10429A0 = 17050016, which is, does not start at 32-byte boundary
}
To directly answer the question - use the align(N) to specify the alignment you want. However, keep this in mind (quote from dlang.org): Do not align references or pointers that were allocated using NewExpression on boundaries that are not a multiple of size_t
Reference manual at http://dlang.org has a section about alignment - http://dlang.org/attribute.html#align .
Say, the T is int - the edge!int is already 24 bytes big on 64-bit architecture.
D is not so different from C in alignment. Check the following (runnable/editable code at: http://dpaste.dzfl.pl/de0121e1):
module so_0001;
// http://stackoverflow.com/questions/11383240/custom-alignment-options-for-an-efficient-quad-edge-implementation
struct edge(T) {
edge* next;
T* data;
uint position;
}
alias edge!int iedge;
alias edge!int[4] qedge;
/* not a good idea for struct... it is a value type...
edge!int new_edge() {
// in the original example it used new... D is not C++ to mix value and reference types! :)
}
*/
import std.stdio;
int main() {
writeln(iedge.sizeof);
// 64bit
// ----------
writeln(iedge.next.offsetof); // 0
writeln(iedge.data.offsetof); // 8
writeln(iedge.position.offsetof); // 16
writeln(qedge.sizeof);
return 0;
}

identify item/class pointer after qsort

first question so please forgive my naiveness here.
I'm diving into a triangulation library for c++, which sorts an array of struct pointers before running it's triangulation method. I'm trying to keep track of one particular struct pointer (XYZ) throughout my app, which updates according to the mouse position. Problem is, whenever the qsort method is applied, this pointer changes. How do I identify or keep track of this struct XYZ pointer?
Here is the struct & sort...
struct XYZ{
double x, y, z;
};
int XYZCompare(const void *v1, const void *v2){
XYZ *p1, *p2;
p1 = (XYZ*)v1;
p2 = (XYZ*)v2;
if(p1->x < p2->x)
return(-1);
else if(p1->x > p2->x)
return(1);
else
return(0);
}
The array of XYZ structs (2 here for testing) with mouse pointer reference...
XYZ *allPointers = new XYZ[100];
allPointers[0].x = 100;
allPointers[0].y = 200;
allPointers[0].z = 0;
allPointers[1].x = 50;
allPointers[1].y = 80;
allPointers[1].z = 0;
XYZ *mousePointer = &allPointers[0];
Sort and update mouse methods.
mousePointer->x = mouseX;
mousePointer->y = mouseY;
// If I don't qsort here the reference is fine, but I need to.
qsort(allPointers, 2, sizeof(XYZ), XYZCompare);
// triangulate, etc
You have a couple of options:
You could search for your unique entry after sorting. If you add a marker member search linearly for the marker. If any entry with a matching X/Y coordinate is as good as any other you could bsearch for it in the sorted array. You could combine those by using bsearch to find the right X coordinate followed by a (shorter) linear search for the marker.
You can add a layer of indirection. Instead of sorting your array of XYZ structures, create a parallel list of indexes or pointers into that array and sort the XYZ * or int references instead. Your mousePointer reference will remain valid.
Shouldn't the third arg to qsort() be size(XYZ*)? You're sorting the pointers and not the objects being pointed to.