2009-11-28 3 views
3

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

Можно ли это сделать?

EDIT: Я пишу на C, но это может быть для любого языка.

+0

Всевозможные платформы имеют это, например. java 'java.util.Linkedlist'. Иди, посмотри. – skaffman

+0

Я предполагаю, что он означает, что индексирование должно быть довольно быстрым. 'java.util.LinkedList' имеет индексирование O (n). – jprete

+0

Вы имеете в виду, что индексы меняются с каждым добавлением/удалением, не так ли? – Anna

ответ

1

Возможно, вы можете использовать дерево для своих целей. Создайте двоичное дерево, которое поддерживает веса каждого узла дерева (где вес равен количеству узлов, прикрепленных к этому узлу, включая себя). Если у вас есть схема балансировки, доступная для дерева, то вставки все равно O (log n), так как вам нужно только добавить их к весам узлов предков. Получение индекса по индексу - O (log n), так как вам нужно только посмотреть на индексы предков вашего нужного узла и двух детей каждого из этих предков.

+0

+1 Это хороший ответ. Одна проблема, которую я вижу с ней, заключается в том, что структура данных упорядочена в соответствии с чем-то, что не ясно (иначе «вставить после этого узла»). Остается выяснить, как сбалансировать дерево, чтобы это свойство оставалось. Это не должно быть слишком сложно (например, с 2-3 деревьями), но оно отличается от обычных сбалансированных деревьев, в которых ключи определяют то, что находится там. – Anna

+0

Да, это определенно проблема. Я бы предположил, что вы сохраните фактические данные внизу в связанном списке, а все внутренние узлы дерева будут содержать только веса. Один алгоритм для этого, что я узнал в град-школе, заключается в том, чтобы оставить дерево (и любое поддерево) одним, пока одна сторона не станет в N раз больше веса другого. Если это свойство верно для любого поддерева после вставки или удаления, восстановите дерево для самого высокого такого поддерева. В среднем это время O (log n). – jprete

0

Для достижения такого массива, как индексирование в таких языках, как C++, Java, Python, нужно было бы перегрузить оператор индексирования массива [] для класса, который реализует структуру данных связанных списков. Реализация будет O (n). В C, поскольку перегрузка оператора невозможна, поэтому нужно было бы написать функцию, которая берет структуру данных связанного списка и позицию и возвращает соответствующий объект.

В случае, если требуется более быстрый доступ к порядку, нужно использовать другую структуру данных, такую ​​как BTree, предложенный jprete или динамическим массивом (который автоматически растет, когда и когда к нему добавляются новые элементы). Быстрый пример: std::vector в стандартной библиотеке C++.

0

элементы строки сервера SQL в clustered index are arranged like so:

. 
/\ 
/\ /\ 
*-*-*-* 

Связанный список в листьях (*-*-*). Связанный список упорядочен, что позволяет осуществлять быстрое направленное сканирование, а дерево служит в качестве «дорожной карты» в связанном списке. Таким образом, для ваших элементов вам понадобится пара ключ-значение, а затем структура данных, которая инкапсулирует дерево и связанный список.

так что ваша структура данных может выглядеть следующим образом:

struct ll_node 
{ 
    kv_pair current; 
    ll_node * next; 
}; 

struct tree_node 
{ 
    value_type value; 
    short isLeaf;   

    union 
    { 
     tree_node * left_child; 
     kv_pair * left_leaf; 
    } 
    union 
    { 
     tree_node * right_child; 
     kv_pair * right_leaf 
    } 
}; 

struct indexed_ll 
{ 
    tree_node * tree_root; 
    ll_node * linked_list_tail; 
}; 
3

Один из способов достижения своей цели является реализация случайного или детерминированного skip list. На нижнем уровне - у вас есть связанный список со своими товарами.

Для доступа к элементам с использованием индексов вам необходимо добавить информацию во внутренние узлы - сколько узлов находится на самом низком уровне, от этого узла до следующего узла на этом уровне. Эта информация может быть добавлена ​​и сохранена в O (logn).

Эта сложность в решении проблемы: Добавить, Удалить, Идти в индекс, все работают в O (logn).

Недостатком этого решения является то, что его гораздо сложнее реализовать, чем обычный связанный список. Поэтому, используя регулярный связанный список, вы получаете «Добавить», «Удалить» в O (1) и «Перейдите к индексу в O (n)».

+0

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

+0

+1. Я не был уверен, как заставить лыжников правильно индексировать. Однако теперь мне кажется, что skiplists - это просто форма автоматически сбалансированного дерева, поэтому вы можете использовать одни и те же базовые структуры узлов. – jprete

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

  • Нет связанных вопросов^_^