Що означає для структури даних "нав'язливою"?


120

Я бачив термін нав'язливий, який використовується для опису структур даних, таких як списки та стеки, але що це означає?

Чи можете ви навести приклад коду нав'язливої ​​структури даних, і чим вона відрізняється від ненав'язливої?

Крім того, навіщо робити це нав'язливим (або, не настирливим)? Які переваги? Які недоліки?

Відповіді:


107

Нав'язлива структура даних - це структура, яка потребує допомоги елементів, які вона збирається зберігати, щоб зберегти їх.

Дозвольте це переформулювати. Коли ви щось вкладаєте в цю структуру даних, це "щось" усвідомлює той факт, що воно є в тій структурі даних, певним чином. Додавання елемента до структури даних змінює елемент.

Наприклад, ви можете побудувати не нав'язливе бінарне дерево, де кожен вузол має посилання на ліве та праве під деревці та посилання на значення елемента цього вузла.

Або ви можете створити нав'язливий, де посилання на ці під-дерева вбудовані у саме значення.

Прикладом нав'язливої ​​структури даних може бути упорядкований перелік елементів, які можна змінювати. Якщо елемент змінюється, список потрібно впорядкувати, тому об’єкт списку повинен втручатися у конфіденційність елементів, щоб отримати їх співпрацю. тобто. елемент повинен знати про список, у якому він знаходиться, та повідомляти про зміни.

ORM-системи зазвичай обертаються навколо нав'язливих структур даних, щоб мінімізувати ітерацію над великими списками об'єктів. Наприклад, якщо ви отримаєте список усіх співробітників у базі даних, а потім зміните ім’я одного з них і хочете зберегти його назад у базі даних, нав'язливий список працівників повідомить, коли об'єкт працівника змінився, оскільки це Об'єкт знає, у якому списку він знаходиться.

Не нав'язливий список не розповідався б і повинен був з’ясувати, що змінилося і як воно змінилося само собою.


8
Я все ще хотів би побачити приклад і плюси і мінуси, але це хороший вступ.
Рудігер

Замість поштового коду я скажу, що STL не є нав'язливим, тоді як Boost.Intrusive - нав’язливий (очевидно).
кам’яний метал

1
Нав'язливі плюси: Не потрібно копіювати свої дані у внутрішню структуру, вона може використовуватися як є. Мінуси: Ви повинні перервати інкапсуляцію своїх даних, щоб підтримувати контейнери, в яких зберігатимуться ваші дані. Ненав'язливі контейнери Плюси: краща інкапсуляція не потребує зміни даних для ваших контейнерів. Мінуси: Потрібна копія даних у внутрішню структуру вузла.
кам’яний метал

3
boost.org/doc/libs/1_45_0/doc/html/intrusive.html містить приклади та хороший опис плюсів і мінусів.
Тоні Делрой

5
Чудове пояснення з прикладами: boost.org/doc/libs/1_55_0/doc/html/intrusive/…
Paweł

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;

Особисто я віддаю перевагу настирливому дизайну, оскільки його прозорість.


Цей заключний рядок цікавий завдяки використанню слова "прозорий", оскільки перебування в нав'язливому контейнері не є прозорим для об'єкта.
Санки

@ArtB Ясніше передати, як саме дані використовуються в кінцевій програмі, у випадку ненав'язливих даних вам зазвичай доводиться копати в контейнери, тоді як для нав'язливих даних ви бачите їх лише з структури даних.
API-Beast

1
Добре, я вважаю, що будь-яке "прозоре" використання прозорого повинно бути кваліфіковане з тієї точки зору. На моєму досвіді, «прозорий» часто використовується для того, щоб вказати на те, як обробка даних не є видимою для домену (тобто моделювання домену є чистою). Якщо термін використовується обома способами, мені цікаво, чи є в ньому якесь значення.
Санки

2
@ArtB О! Існує якесь особливе значення для інформатики для прозорого! Прозорість для мене означає, що ви можете бачити внутрішні органи, наприклад, "не перешкоджаючи перегляду", як, наприклад, термін використовується в будь-якому не-cs контексті.
API-Beast
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.