2013-03-19 9 views
1

Мне нужна структура данных, в которой хранятся кортежи, и позволит мне выполнить запрос, например: заданный кортеж (x,y,z) целых чисел, найти следующий (увеличенная граница для него). Под этим я подразумеваю рассмотрение естественного порядка (a,b,c)<=(d,e,f) <=> a<=d and b<=e and c<=f. Я попробовал сортировку MSD radix, которая разбивает элементы на ведра и сортирует их (и делает это рекурсивно для всех позиций в кортежах). Есть ли у кого-нибудь другое предложение? В идеале я хотел бы, чтобы запрос abouve выполнялся внутри O (log n), где n - количество кортежей.Структура данных для индексирования кортежа

+0

Если у вас есть abc of (2,2,2), который является следующим верхним (3,1,3) или (3,2,2) или даже (2,3,3)? Желание быть ясными по желаемому порядку. – rlb

+0

Спасибо. Прошу прощения за то, что я не был достаточно конкретным. Предположим, мы смогли преобразовать каждый кортеж в соответствующее целое число 10. Далее будет _smallest_ такое целое число, которое больше текущего. Итак, в вашем примере (2,2,2) <(2,3,3) <(3,1,3) <(3,2,2). – user1377000

+0

И, кстати, преобразование в базу 10 не может быть и речи, если вы хотите предложить что-то подобное :) (учитывая потенциально огромную арность и ограничение на 4 или 8 байтов). – user1377000

ответ

2

Два варианта.

Используйте двоичный поиск по отсортированному массиву. Если вы построите ключи (при условии 32bit int) 'с (a < < 64) | (b < 32) | c и удерживайте их в простом массиве, упакованном один рядом с другим, вы можете использовать бинарный поиск, чтобы найти значение вы ищете (если используете C, для этого есть даже функция библиотеки), а следующая - просто одна позиция. Худший случай Производительность - O (logN), и если вы можете сделать http://en.wikipedia.org/wiki/Interpolation_search, то вы можете даже приблизиться к O (log log N)

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

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

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

Я также вижу, что у вас был аналогичный вопрос по этим строкам, поэтому я думаю, что кишки того, что я говорю, объединяют A, b, c, чтобы создать один длинный ключ и использовать его с бинарным поиском, хэшем или даже б-дерево. Если длина ключа - ваша проблема (какой язык), можете ли вы рассматривать ее как строку?

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

+0

На самом деле это отличный ответ.Есть две вещи непонятные: 1) Каково было бы преимущество B-дерева над, скажем, сбалансированным двоичным деревом поиска, в этом случае? (есть один?) 2) Я использую Java. Что делать, если я использовал что-то вроде BigInteger? Я мог бы также вычислить ключ каждый раз, когда это необходимо. – user1377000

+0

Кроме того, какова была бы сложность сравнения ключей? – user1377000

+0

Первый вариант - это простой массив, а не дерево. Определено таким образом: struct {int key [3]; данные...; } theArray [NNN]; для поиска вы начинаете его по середине NNN/2, затем идите вверх или вниз в зависимости от сравнения. При сравнении ключей вы проверяете ключ [0], и только нужно проверять ключ [1], если значения равны, althougth примеры в http://en.wikibooks.org/wiki/Algorithm_Implementation/Search/Binary_search в java кажутся чтобы охватить множество примеров. – rlb

Смежные вопросы