I am trying to design a program that takes in data from a file, after which it gives numbering to unique data, linked list also contains parent and child lists.
Data
What you are describing is a Graph.
A (double) Linked list is really just a one dimensional list and is an inappropriate term for what you want.
There are two main ways of implementing a graph:
n
times n
matrix (where n
is the amount of nodes/vertices) with an entry at [a][b]
if node a
has an edge to b
.Which of these to use depends on your use case. As a rule of thumb: If you have many many vertices (tens of thousands) and you can on average cap the amount of edges per vertex with a constant then you should use lists. In the other use cases you should be better off with a matrix (mainly because of ease of implementation).
I assume that your use case is limited to ASCII letters, so I would actually use a matrix here. With proper optimisations (bitfields and the likes) you can browse it very quickly.
Your implementation could look like:
char adj_matrix[0x80][0x80]; // I am assuming that you only have ASCII letters
memset(adj_matrix, 0, sizeof(adj_matrix)); // initialise empty
Inserting elements would go like:
adj_matrix['A']['C'] = 1; // edge from A --> C
To determine all incoming edges for 'A' you would have to iterate though the matrix:
for (i = 'A'; i <= 'Z'; i++)
if (adj_matrix[i]['A'])
// A has an incoming edge from i
for outgoing the other way round
for (i = 'A'; i <= 'Z'; i++)
if (adj_matrix['E'][i])
// E has an outgoing edge to i
As said, you can significantly up both space and time performance with the use of bitfields and bitscan instructions (e.g. gcc __builtin_clzll
, icc _bit_scan_reverse
).