Что значит «навязчивая» структура данных?

120

Я видел термин навязчивый, используемый для описания структур данных, таких как списки и стеки, но что он означает?

Можете ли вы привести пример кода навязчивой структуры данных и чем она отличается от ненавязчивой?

Кроме того, зачем делать это навязчивым (или ненавязчивым)? Каковы преимущества? Какие недостатки?

Рудигер
источник

Ответы:

107

Навязчивая структура данных - это такая структура, которая требует помощи от элементов, которые она намеревается хранить, чтобы сохранить их.

Позвольте мне перефразировать это. Когда вы помещаете что-то в эту структуру данных, это «что-то» каким-то образом узнает о том, что оно находится в этой структуре данных. Добавление элемента в структуру данных изменяет элемент.

Например, вы можете построить ненавязчивое двоичное дерево, в котором каждый узел имеет ссылку на левое и правое поддеревья и ссылку на значение элемента этого узла.

Или вы можете создать навязчивое дерево, в котором ссылки на эти поддеревья встроены в само значение.

Примером навязчивой структуры данных может быть упорядоченный список изменяемых элементов. Если элемент изменяется, список необходимо переупорядочить, поэтому объект списка должен нарушить конфиденциальность элементов, чтобы добиться их взаимодействия. то есть. элемент должен знать список, в котором он находится, и сообщать ему об изменениях.

ORM-системы обычно вращаются вокруг навязчивых структур данных, чтобы минимизировать итерацию по большим спискам объектов. Например, если вы получите список всех сотрудников в базе данных, затем измените имя одного из них и захотите сохранить его обратно в базу данных, навязчивый список сотрудников будет сообщен при изменении объекта сотрудника, потому что это объект знает, в каком списке он находится.

Ненавязчивый список не будет сообщен, и ему придется выяснить, что изменилось и как изменилось само по себе.

Лассе В. Карлсен
источник
8
Я все еще хотел бы увидеть пример, плюсы и минусы, но это хорошее введение.
Рюдигер,
Вместо публикации кода я скажу, что STL не навязчив, а Boost.Intrusive навязчив (очевидно).
Stonemetal
1
Навязчивые плюсы: нет необходимости копировать данные во внутреннюю структуру, их можно использовать как есть. Минусы: вы должны прервать инкапсуляцию ваших данных, чтобы поддерживать контейнеры, в которых будут храниться ваши данные. Это может стать сложным, если ваши данные должны находиться в нескольких контейнерах. Неинтрузивные контейнеры Плюсы: Лучшая инкапсуляция, нет необходимости изменять данные для ваших контейнеров. Минусы: требуется копия ваших данных во внутренней структуре узла.
Stonemetal
3
boost.org/doc/libs/1_45_0/doc/html/intrusive.html содержит примеры и хорошее описание плюсов и минусов.
Тони Делрой
5
Отличное объяснение с примерами: boost.org/doc/libs/1_55_0/doc/html/intrusive/…
Paweł Szczur,
22

В интрузивном контейнере сами данные отвечают за хранение необходимой информации для контейнера. Это означает, что с одной стороны тип данных должен быть специализирован в зависимости от того, как он будет храниться, с другой стороны, это означает, что данные «знают», как они хранятся, и, таким образом, могут быть немного лучше оптимизированы.

Неинтрузивная:

template<typename T>
class LinkedList
{
  struct ListItem
  {
    T Value;
    ListItem* Prev;
    ListItem* Next;
  };

  ListItem* FirstItem;
  ListItem* LastItem;

  [...]
  ListItem* append(T&& val)
  {
    LastItem = LastItem.Next = new ListItem{val, LastItem, nullptr};
  };
};

LinkedList<int> IntList;

Интрузивный:

template<typename T>
class LinkedList
{
  T* FirstItem;
  T* LastItem;

  [...]
  T* append(T&& val)
  {
    T* newValue = new T(val);
    newValue.Next = nullptr;
    newValue.Prev = LastItem;
    LastItem.Next = newValue;
    LastItem = newValue;
  };
};

struct IntListItem
{
  int Value;
  IntListItem* Prev;
  IntListItem* Next;
};

LinkedList<IntListItem> IntList;

Лично я предпочитаю навязчивый дизайн за его прозрачность.

API-Beast
источник
Это последняя строка любопытно на счете использования слова «прозрачного» , так как , находясь в навязчивом контейнере не прозрачно для объекта.
Sled
@ArtB Это яснее в передаче того, как данные используются именно в конечном приложении, в случае неинтрузивных данных вам обычно приходится копаться в контейнерах, в то время как для навязчивых данных вы видите их только по структуре данных.
API-Beast
1
Что ж, я полагаю, что любое использование «прозрачного» или «прозрачного» должно быть квалифицировано с какой точки зрения. По моему опыту, термин «прозрачный» часто используется для обозначения того, как обрабатываются данные, невидимо для домена (т.е. моделирование предметной области является чистым). Если этот термин используется в обоих направлениях, мне интересно, есть ли в нем какое-то значение.
Sled
2
@ArtB Ой! В информатике есть особое значение для прозрачного! «Прозрачность» для меня означает, что вы можете видеть внутреннее, например, «не мешать обзору», как этот термин используется в любом контексте, отличном от CS.
API-Beast