0

i am learning data structures and while doing linked list i was thinking whether there is another type of declaration other than self referential structures in C for implementing linked list.

this is the first time i need to use structures in C and everyone uses only self referential structures for implementation.I would like to know if there is any other possible way of implementing linked list with out self referential structure.

Madhu
  • 1
  • 1
  • 1
    There is no "reference" in C. For linked list, the "node" structure will have at least one pointer for self type. – MayurK Sep 27 '19 at 10:11
  • 4
    You can implement it using an array. See https://stackoverflow.com/questions/10477754/implement-linked-list-using-array-advantages-disadvantages and https://stackoverflow.com/questions/7665607/how-do-you-implement-a-linked-list-within-an-array – Rishikesh Raje Sep 27 '19 at 10:12
  • 1
    I don't think there is because the list must have a data element "next" that points to the next list element, so "list points to list points to..." and so it needs to reference itself (also called a recursive data structure). – Paul Ogilvie Sep 27 '19 at 10:37
  • Note also that a list has an undetermined legth. Rishikesh' idea of an array often has a finite length of the list (though with realloc you can let it grow, but realloc and arrays use a _contiguous_ block of memory and normal lists don't, making it easier for the memory allocator). – Paul Ogilvie Sep 27 '19 at 10:40
  • 1
    There are ways (the first one I thought of is the one discussed in the questions linked by @RishikeshRaje), but I doubt there are any *good* ways. Using self-referential structures is a powerful and useful technique, and just about everyone agrees it's the Right way to implement linked data structures like trees and lists. Are you asking out of curiosity, or is there some reason you feel you can't use self-referential structures? – Steve Summit Sep 27 '19 at 10:40
  • It sounds like an http://xyproblem.info/ – John Sep 27 '19 at 11:25
  • 2
    @MayurK In the question "self-referential" means the same thing you mean when you say "pointer for self type". That it, the struct's definition includes mentions of the struct (i.e., it refers to itself when declaring itself). It's obviously not being used to mean a C++ "reference". – L. Scott Johnson Sep 27 '19 at 11:29
  • It's not unknown to use an array of structs with only a single byte as link indices. I often use such a list in embedded systems, e.g. as object pools/queues. – Martin James Sep 27 '19 at 11:29
  • @MartinJames - sure, I do that too (for example, within a Hash Map). Sometimes I use an array like you mentioned and sometimes I use a bitmap for object pools (I'm sure there are even more embedded system approaches)... however, these don't really represent a linked list in the traditional sense, they are more like a specific, custom, object pool type of data structure ;-) – Myst Sep 27 '19 at 11:37
  • Possible duplicate of [What is a faithful alternative to a linked list in C?](https://stackoverflow.com/questions/29164110/what-is-a-faithful-alternative-to-a-linked-list-in-c) – John Sep 27 '19 at 11:41
  • 1
    @RishikeshRaje That implementation is self-referential in exactly the same way as a conventional linked list implementation. It’s just that, rather than using strongly-typed pointers to a struct, it’s using weakly typed indices to integers. That doesn’t make it less self-referential though. And the reason is simple: a linked list is *by definition* self-referential. It cannot be implemented differently because then it ceases being a linked list. – Konrad Rudolph Sep 27 '19 at 14:03
  • @Madhu Are you trying to separate the code for the linked list structure from the data types that use the linked list? In other words, are you trying to write a single linked list structure that can be used with many different kinds of data? – Lee Jenkins Sep 27 '19 at 20:27
  • @KonradRudolph and others, The method of arrays is another way of implementing a linked list which is useful in some limited cases. – Rishikesh Raje Sep 28 '19 at 04:18
  • @RishikeshRaje I’m aware (and I’ve literally used this in the past). I’m just saying that it doesn’t fulfil OP’s requirement of avoiding self reference. It just doesn’t encode the self reference in the type system, but it’s still there because *that’s how linked lists are defined*. – Konrad Rudolph Sep 28 '19 at 11:38
  • @KonradRudolph I do not disagree with you here. I guess one can see an array implementation as also self referential (even though weakly typed) – Rishikesh Raje Sep 28 '19 at 12:04

2 Answers2

1

I was thinking whether there is another type of declaration other than self referential structures in C for implementing linked list.

No, linked lists can only be implemented by using an explicit or implicit pointer to their own type.

Masking this self reference using void* pointers is possible, but it only complicates the code, making the self reference implicit and making it more difficult to read the code.

Arrays:

Sure, you could use an unordered array and make it "ordered" by an internal indexing scheme that looks like a linked list - but it still be an array and it will not have the same behavior as a classical linked list.

For example, your array based linked list may be bounded to a pre-selected number of elements (selected during compilation), causing higher memory consumption when the list isn't full and making it impossible to add elements after a certain point.

On the flip side, if your array based linked list is dynamic, item copying during realloc may introduce performance costs (for example, making an O(1) operation perform at O(n)).

Another thing to think about is that a linked list based on a dynamic array will cause pointers to the data to be invalidated every time the array changes its address (realloc).

Myst
  • 18,516
  • 2
  • 45
  • 67
  • I upvoted the answer but your last paragraph is wrong. You can implement allocation in amortised O(1). After all, that’s what `malloc` does. Implementing a linked list via an array is in fact what happens under the hood anyway, where the “array” is simply the heap memory space. – Konrad Rudolph Sep 28 '19 at 11:40
  • @KonradRudolph , thank you for your comment. One of the main differences is that a classical linked list allows for non-continuous memory fragments while an array based linked list requires a single block of continuous memory. However, I don’t see `realloc` promising O(1) and, as a result, I can’t see how extending the array beyond it’s initial capacity would be O(1). – Myst Sep 28 '19 at 11:55
  • Right, your linked list size would be bounded. As is every linked list: by the size of the heap (i.e. addressable virtual memory). And the heap is as continuous as your array. Successive list elements *inside* it aren’t. – Konrad Rudolph Sep 28 '19 at 17:14
  • @KonradRudolph - I attempted to clarify my statement, I hope this helps. I don't think the details related to virtual addresses change much (definitely not for OPs question). Also, a classical linked list is like grains of sand, whereas an array based linked list is more similar to paged sized rocks. The heap will fit more grains of send (assuming allocator overhead isn't stupid). Performance for a classical linked list will be different than performance for an array based linked list due to memory management alone. `realloc` optimizations (which avoid copying) help, but don't change this. – Myst Sep 28 '19 at 17:30
0

What you want is to implement a map with 3 keys:

  • the current node
  • the next node
  • the previous node

Something like this:

struct {
    int currentNode;
    int nextNode;
    int prevNode;
} MapEntry_t;

and then have a dynamic (or static) array of these, something like:

struct MapEntry_t myLinkedList[10];

Edit: I should clarify that the ints are used as indices not as pointers.

John
  • 1,012
  • 14
  • 22
  • No, definitely not... `int` doesn't necessarily allow for all pointer type offsets. For example, on my macOS machine, `int` is 4 bytes long and `void *` is 8 bytes long. Using `int` you will loose information and might end up with a corrupted data structure. – Myst Sep 27 '19 at 11:16
  • 1
    @Myst I think I confused you. Those ints are not meant to be used as pointers. They are just indices. – John Sep 27 '19 at 11:17
  • you're right, I was confused by your answer, because the question was about a **linked list**, not an **array**, whereas your answer is about an unordered array with an internal ordering structure. – Myst Sep 27 '19 at 11:20
  • 2
    @Myst The OP is trying to implement a linked linked list without self referring structures, which sort of defies the meaning of a linked list, so it can get rather confusing. – John Sep 27 '19 at 11:22
  • this is why the answer you OPs question should be "No, linked lists can only be implemented by using an explicit or implicit pointer to their own type. Masking this self referencing using `void*` pointers is possible, but it only complicates the code, making the self reference implicit." – Myst Sep 27 '19 at 11:26
  • @Myst That's a good answer, please post it – John Sep 27 '19 at 11:28