Article based on Linked Lists by computerquip revision 2:
Linked lists are a basic concept in almost all programming languages, including interpreted and higher level languages. All a linked list is is a structure that holds a list of structures containing a way to iterate to the next and/or last object via reference. In C++, we are given an implementation of an advanced doubly linked taking advantage of templates which we call std::list. I will explain what doubly linked means, etc. In C, the standard library does not provide any containers at all, which isn't necessarily bad but this forces you to make your own. The following example will work with both C and C++ (or should):
1 2 3 4 5 6
|
typedef struct Node
{
void * data; //Data to be held inside of node
//In C, one would normally just place a type here.
Node * next; //Next element of data
};
| |
This is called a singly linked list node since it only holds a single link which happens to be the next link in the list. Commonly, this is all there is to a C list implementation. Some go further though, mainly to build something to make the list a little bit more usable:
1 2 3 4 5
|
typedef struct List
{
Node * list; //Array of nodes.
//Node * last; //Sometimes people add a pointer directly to the beginning or end of a list.
};
| |
This struct alone gives access to the first pointer of the linked list, an overall access to the list, and lets the user build whatever he wants on top of it. You'll also find people who create functions like "next()" etc. This is relatively simple to use inside of a main program as well:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
//Please note that this does not use the List struct.
//It looks sloppy to use it unless your using a doubly linked list.
typedef struct Node
{
int data; //We could define an ENUM to choose which type we want, but no point.
Node * next;
};
int main(int argc, char ** argv)
{
Node * nodes = malloc(sizeof(Node)); //Beginning link.
const int sizeoflist = 5; //5 is random.
//Don't let this hurt you. When you make a list, it should be obvious when you add elements.
Node * iter = nodes; //an iterator so we don't forget the first link of the chain.
for (int i = 0; i != sizeoflist; i++) //I don't know if this is right.
{
(*iter).next = malloc(sizeof(Node));
(*iter) = (*iter).next; //iterate to the next element and reassign.
}
}
| |
This simply makes a five element list which contains no data. This is just an example though and sizeoflist is unrealistic. You should ALWAYS know when to add elements to the list. If not, then a list isn't the correct container to use.
As you could probably imagine, we could do so much more with C++ classes and templates, it's not even funny:
editing...