Это звучит как точечные данные в трехмерном пространстве, в основном. Существует много решений этой проблемы, и выбор наилучшего зависит от диапазона и распределения ваших индексов, а также от ваших схем доступа к данным. Последнее особенно важно - вы выбираете случайным образом набор значений в качестве своего ключа и хотите посмотреть, существует ли там четверка данных, или вы получаете к ним более регулярный доступ? Различные структуры данных предлагают очень разные затраты для регулярного и случайного доступа.
Ради описания я буду называть ваши квадраты данных {X, Y, Z, W}, где {X, Y, Z} - ваш ключ, а W - значение, связанное с этим ключом.
Если у вас есть прямоугольный диапазон Xmin-to-Xmax, Ymin-to-Ymax, Zmin-to-Zmax, и этот диапазон плотно заполнен, так что каждый X, Y и Z в этом диапазоне имеет данные связанный с ним, вы просто используете трехмерный массив, индексированный по X, Y и Z, где W хранится в каждой точке этого массива.
Если у вас есть что-то вроде этого, за исключением того, что только с некоторыми значениями связаны квадраторы данных, но их доля достаточно велика (скажем, 25% или более), тогда вы все равно можете использовать трехмерный массив и в каждой точке этого массива вы либо сохраняете значение W, либо «ничего». Если вам нужно уметь ответить на вопрос о том, присутствует ли триплет X, Y, Z в вашем наборе данных, вы либо сохраняете невозможное значение W (-1, возможно, если они являются положительными целыми числами, либо INT_MAX, если они в противном случае), или в каждой точке вы сохраняете структуру целого числа W и логического флага «is_present» и устанавливаете для флага значение true / false, если этот индекс присутствует в вашем наборе данных.
Если ваши квадраты данных более разрежены, но индексы все еще находятся в разумных пределах, вы можете использовать структуру, называемую октодеревом, для представления набора данных. В Википедии есть описание с диаграммами: http://en.wikipedia.org/wiki/Octree. По сути, вы делите диапазон возможных индексов на 8 октантов. Если в этом октанте всего несколько квадов данных, вы сохраняете их список; в противном случае вы рекурсивно делите этот октант на 8 субоктантов и повторяете. В конце концов вы получаете это дерево октантов и субоктантов, и каждый лист дерева представляет собой небольшой список квадратов данных. Даже если найти одну точку в дереве дорого (нужно пройти по дереву сверху вниз), дешево найти соседних соседей, дешево найти несколько точек в одном и том же пространстве и действительно дешево перебрать все точки в дереве.