Для чего-то подобного вам не нужно динамическое распределение памяти.Вместо этого вам нужен массив, который использует значение индекса указанного элемента вместо фактического указателя.
Предположим, вы хотите реализовать двоичное дерево.Вы можете смоделировать его следующим образом:
struct tree {
int free;
int value;
int left;
int right;
};
Поля left
и right
содержат индексы узлов слева и справа от данного узла, причем значение -1 указывает на отсутствиетакой узел (т. е. он эквивалентен указателю NULL в этом контексте).
Поле free
можно использовать в качестве флага, чтобы определить, используется ли данный элемент массива в данный момент.Если узел помечен free
, равным 1, поле left
указывает на следующий свободный узел, что облегчает поиск свободных узлов.
Узел 0 особенный, поскольку он является началомсвободный список, а поле right
указывает на корневой узел дерева.
Тогда следующее дерево:
7
/ \
3 10
/ \ / \
1 4 8 12
Может быть смоделировано следующим образом:
free value left right
---------------------------
0 | 1 | 0 | 8 | 1 |
---------------------------
1 | 0 | 7 | 2 | 3 |
---------------------------
2 | 0 | 3 | 4 | 5 |
---------------------------
3 | 0 | 10 | 6 | 7 |
---------------------------
4 | 0 | 1 | -1 | -1 |
---------------------------
5 | 0 | 4 | -1 | -1 |
---------------------------
6 | 0 | 8 | -1 | -1 |
---------------------------
7 | 0 | 12 | -1 | -1 |
---------------------------
8 | 1 | 0 | 9 | -1 |
---------------------------
9 | 1 | 0 | -1 | -1 |
---------------------------
Такое дерево можно либо записать в карту, либо сохранить в памяти, используя malloc
/ realloc
для управления размером.
Если в вашей структуре данных содержится какая-либо строка, вам понадобитсяструктура для хранения символьных массивов фиксированного размера вместо указателей для правильной сериализации.