0

I want to design a data structure where I have intermediate lock entities among elements. These locks are common to the two adjacent elements.

E(i) are deque where addition of element to it controlled by B(i) and B(i+1). E can be split. E(i) and E(i+1) could be merged to form E(i) with removal of B(i+1). Removal of E is forbidden.

What will be the best data structure for this in C++.

Diagram

getsuha
  • 711
  • 6
  • 16
  • You can use `std::list` to achieve that. – πάντα ῥεῖ Feb 07 '17 at 10:31
  • @πάνταῥεῖ - There are no boundary elements when using `std::list`. I think they have some function and cannot be omitted. – StoryTeller - Unslander Monica Feb 07 '17 at 10:33
  • @StoryTeller As it looks from the image the boundary elements are nothing more than generic doubly linked-list nodes. – πάντα ῥεῖ Feb 07 '17 at 10:34
  • So which is it? Do the boundary elements have some sort of substance? If not than a `std::list` is the way to go. – StoryTeller - Unslander Monica Feb 07 '17 at 10:38
  • Depending on the access patterns of course, but in the majority of cases std::vector is your answer. Linked lists are really bad with regards to cache utilization, so very very slow. – aerkenemesis Feb 07 '17 at 10:47
  • What happen if you want to remove `E2` ? skip `B2` or `B3` ? – Jarod42 Feb 07 '17 at 11:03
  • @StoryTeller The Boundary elements have substances, let say only a a boolean data which both the adjacent element needs to know. – getsuha Feb 07 '17 at 11:21
  • @Jarod42 If one removed E2 then B2 and B3 should be merged or let say we keep B2 or B3. – getsuha Feb 07 '17 at 11:22
  • @saha Explain the operations you need to support and their exact behaviour *in detail* (no vague examples) in the question. Handing out occasional hints in the comments will lead nowhere. – molbdnilo Feb 07 '17 at 11:24
  • We may consider it as a [Path graph](https://en.wikipedia.org/wiki/Path_graph). So what is a good data structure for this type of data. – getsuha Feb 07 '17 at 11:24
  • @molbdnilo Let say E(i)s are arrays and B(i)s are lock entity. So the Es can grow in left if the corresponding B is unlocked and else not. Now B3 is common to E2 and E3. So if B3 is in locked condition, both E2 and E3 should have that information and should not be allowed to grow in that direction. Behaviors desired to supports are as follows.. 1. Insertion of B or we can say split of E. 2. Removal of B or we can say merge of two Es. 3. Removal of E should not be allowed. – getsuha Feb 07 '17 at 11:31
  • @saha Read the parts where I wrote "in the question" and "no vague examples" again. (If you write "let's say" or "we can say", you're being vague.) – molbdnilo Feb 07 '17 at 12:02
  • @molbdnilo Thanx for your advice. I have edited the question. – getsuha Feb 07 '17 at 12:38

1 Answers1

1

Standard library has no heterogeneous data structures. You have three approaches: Implement one yourself, use a homogeneous structure that contains objects of a tagged union type, or use two parallel structures.

A minimal example of a heterogeneous list:

template<class T,class E>
struct node;

template<class T, class E>
struct edge {
    node<T, E> *prev, *next;
    E data;
};

template<class T, class E>
struct node {
    edge<T, E> *prev, *next;
    T data;
};

template<class T, class E>
struct fancy_list {
    edge<T, E> *head, *tail;
};

struct wagon {
    // wagon members
};
struct boundary {
    // boundary members
};

int main() {
   fancy_list<wagon, boundary> wagons;
}

The algorithms will work mostly the same way as algorithms for homogeneous lists, but you will have to develop a strategy for dealing with removal of nodes (Is one edge removed? Which one? Or are they merged? How?) and insertion (insert before or after existing edge? Copy existing edge members to the new one, or set a default state?) etc. There are no "right" or "best" solutions without a well defined use case.


A tagged union implementation std::variant will be introduced in the C++17. Until then you will have to implement your own, or depend on a third party.

The problem with this approach is that the data structure doesn't inherently enforce the invariant of edges neighboring only nodes and nodes only neighboring edges, so you will need to implement your own set of algorithms anyway.


The parallel structures for edges and nodes is a typical way of implementing a graph. Your list is simply a special case of graph that has exactly two edges for each node.

eerorika
  • 232,697
  • 12
  • 197
  • 326