Pull to refresh
  • by relevance
  • by date
  • by rating

Дерево Фенвика

Алгоритмы
Sandbox
Здравствуй, Хабрахабр. Сейчас я хочу рассказать о такой структуре данных как дерево Фенвика. Впервые описанной Питером Фенвиком в 1994 году. Данная структура похожа на дерево отрезков, но проще в реализации.

Что это?


Дерево Фенвика — это структура данных, дерево на массиве, которая обладает следующими свойствами:
• позволяет вычислять значение некоторой обратимой операции F на любом отрезке [L; R] за логарифмическое время;
• позволяет изменять значение любого элемента за O(log N);
• требует памяти O(N);
Читать дальше →
Total votes 81: ↑73 and ↓8 +65
Views41.7K
Comments 37

B-tree

Алгоритмы
Sandbox

Введение


Деревья представляют собой структуры данных, в которых реализованы операции над динамическими множествами. Из таких операций хотелось бы выделить — поиск элемента, поиск минимального (максимального) элемента, вставка, удаление, переход к родителю, переход к ребенку. Таким образом, дерево может использоваться и как обыкновенный словарь, и как очередь с приоритетами.

Основные операции в деревьях выполняются за время пропорциональное его высоте. Сбалансированные деревья минимизируют свою высоту (к примеру, высота бинарного сбалансированного дерева с n узлами равна log n). Большинство знакомо с такими сбалансированными деревьями, как «красно-черное дерево», «AVL-дерево», «Декартово дерево», поэтому не будем углубляться.

В чем же проблема этих стандартных деревьев поиска? Рассмотрим огромную базу данных, представленную в виде одного из упомянутых деревьев. Очевидно, что мы не можем хранить всё это дерево в оперативной памяти => в ней храним лишь часть информации, остальное же хранится на стороннем носителе (допустим, на жестком диске, скорость доступа к которому гораздо медленнее). Такие деревья как красно-черное или Декартово будут требовать от нас log n обращений к стороннему носителю. При больших n это очень много. Как раз эту проблему и призваны решить B-деревья!

B-деревья также представляют собой сбалансированные деревья, поэтому время выполнения стандартных операций в них пропорционально высоте. Но, в отличие от остальных деревьев, они созданы специально для эффективной работы с дисковой памятью (в предыдущем примере – сторонним носителем), а точнее — они минимизируют обращения типа ввода-вывода.
Читать дальше →
Total votes 82: ↑75 and ↓7 +68
Views143.7K
Comments 32

Bitcoin. Как это работает

Криптография
О Bitcoin я узнал относительно недавно, но он меня сразу подкупил своей идеей p2p. Чем глубже я зарывался в их Wiki, тем больше проникался этой идеей. Ее реализация красива и элегантна с технической точки зрения.

Поиск хабра по Bitcoin выдает два топика. Но это скорее новости. По комментариям заметно, что у многих людей, особенно не знакомых с Bitcoin напрямую, возникает много вопросов насчет принципов его работы. Также много догадок, зачастую неверных. Чтобы как-то прояснить ситуацию, было решено написать эту статью.
Читать дальше →
Total votes 111: ↑99 and ↓12 +87
Views731.1K
Comments 219

Еще одна визуализация ряда алгоритмов и структур данных

Алгоритмы

Университет Сан-Франциско создал с использованием HTML5 коллекцию визуализаций различных алгоритмов и структур данных. Посмотреть и потыкать кнопки можно вот тут.
Список визуализированных алгоритмов и структур данных со ссылками под катом.
Читать дальше →
Total votes 82: ↑79 and ↓3 +76
Views17.8K
Comments 17

AVL деревья и широта их применения

Поисковые технологии
Решил немного описать на мой взгляд самую полезную древовидную структуру. AVL дерево это бинарное дерево (у каждой вершины не более 2 сыновей), в котором каждой вершине присвоен идентификатор (как раз его и хранит дерево), идентификаторы подчиняются следующему правилу: ID левого сына<ID родителя<ID правого сына.
Т.е. если обходить дерево рекурсивно слева направо получим отсортированный по возрастанию список ID, справа налево – по убыванию.
Причем дерево максимально сбалансировано: высота левого поддерева отличается от высоты правого максимум на 1.

Интересно в нем то, что тогда на проверку существования элемента в дереве уходит log(N) N – количество ID. Ведь надо пройти от корня вниз, а поскольку дерево максимально симметрично то его высота — log(N)+1
Хорошая новость – нам никто не запрещает прикрепить к вершине еще какие-то полезные данные и тогда выборка произвольных данных по ID будет занимать log(N) времени
Плохая новость – одинаковые ID как следует из определения в нем существовать не могут. Придется делать финт ушами, один способ сделать вместо каждой вершины список вершин с одинаковым ID, другой – изменить алгоритм балансировки.
Читать дальше →
Total votes 23: ↑18 and ↓5 +13
Views7.5K
Comments 9

Работа с умом, а не руками: пример увеличения производительности редактирования текста в Emacs

Программирование
Sandbox

История


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

Это был Bash-скрипт для автоматизации процесса сборки на различных Unix-ах и, реальность такова, что между моей средой и средой сервера сборки небыло ничего общего.
Читать дальше →
Total votes 30: ↑25 and ↓5 +20
Views1.7K
Comments 26

Дерево ван Эмде Боаса

Алгоритмы
Всем доброго времени суток!

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

Дерево ван Эмде Боаса (van Emde Boas tree) — ассоциативный массив, который позволяет хранить целые числа в диапазоне [0; U), где U = 2k, проще говоря, числа, состоящие не более чем из k бит. Казалось бы, зачем нужно еще какое-то дерево, да еще позволяющее хранить только целые числа, когда существует множество различных сбалансриованных двоичных деревьев поиска, позволяющих выполнять операции вставки, удаления и прочие за O(log n), где n — количество элементов в дереве?

Главная особенность этой структуры — выполнение всех операций за время O(log(log(U))) независимо от количества хранящихся в ней элементов.

Что же там еще есть такого вкусного?
Total votes 192: ↑190 and ↓2 +188
Views15.8K
Comments 39

Для чего нужен hash-set

Программирование
Структура данных hash-set (и вообще set) — это такая редкая структура, что присутствует не во всех стандартных библиотеках. В .NET Framework, например, она появилась только с версии 3.5. Однако в некоторых случаях hash-set может быть весьма полезен.

В этой статье я покажу, когда имеет смысл применять hash-set и чем за это придется заплатить.

Читать дальше →
Total votes 11: ↑3 and ↓8 -5
Views76K
Comments 14

Структуры данных в картинках. LinkedList

Java
Приветствую вас, хабражители!

Продолжаю начатое, а именно, пытаюсь рассказать (с применением визуальных образов) о том как реализованы некоторые структуры данных в Java.



В прошлый раз мы говорили об ArrayList, сегодня присматриваемся к LinkedList.

LinkedList — реализует интерфейс List. Является представителем двунаправленного списка, где каждый элемент структуры содержит указатели на предыдущий и следующий элементы. Итератор поддерживает обход в обе стороны. Реализует методы получения, удаления и вставки в начало, середину и конец списка. Позволяет добавлять любые элементы в том числе и null.

Прочитать чуть больше
Total votes 50: ↑46 and ↓4 +42
Views442.8K
Comments 22

Структуры данных в картинках. HashMap

Java
Приветствую вас, хабрачитатели!

Продолжаю попытки визуализировать структуры данных в Java. В предыдущих сериях мы уже ознакомились с ArrayList и LinkedList, сегодня же рассмотрим HashMap.



HashMap — основан на хэш-таблицах, реализует интерфейс Map (что подразумевает хранение данных в виде пар ключ/значение). Ключи и значения могут быть любых типов, в том числе и null. Данная реализация не дает гарантий относительно порядка элементов с течением времени. Разрешение коллизий осуществляется с помощью метода цепочек.

А почему бы и нет?
Total votes 81: ↑75 and ↓6 +69
Views923.1K
Comments 41

Структуры данных в картинках. ArrayList

Java
Приветствую вас, хабралюди!

Взбрело мне в голову написать несколько статей, о том как реализованы некоторые структуры данных в Java. Надеюсь, статьи будут полезны визуалам (картинки наше всё), начинающим java-визуалам а также тем кто уже умеет писать new ArrayList(), но слабо представляет что же происходит внутри.



Сегодня поговорим о ArrayList-ах

ArrayList — реализует интерфейс List. Как известно, в Java массивы имеют фиксированную длину, и после того как массив создан, он не может расти или уменьшаться. ArrayList может менять свой размер во время исполнения программы, при этом не обязательно указывать размерность при создании объекта. Элементы ArrayList могут быть абсолютно любых типов в том числе и null.

Поверить на слово
Total votes 89: ↑82 and ↓7 +75
Views766.9K
Comments 66

Свой инструмент нужно знать в лицо: обзор наиболее часто используемых структур данных

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

Вопрос: Почему поиск в python dict на больших объемах данных быстрее чем итерация по индексированному массиву?

Ответ: В dict хранятся хэши от ключей. Каждый раз, когда мы ищем в dict значение по ключу, мы сначала вычисляем его хэш, а потом (внезапно), выполняем бинарный поиск. Таким образом, сложность составляет O(lg(N))!

На самом деле никакого бинарного поиска тут нет. И сложность алгоритма не O(lg(N)), а Amort. O(1) — так как в основе dict питона лежит структура под названием Hash Table.

Причиной неверного ответа было то, что я не удосужился досконально изучить те структуры, которые лежат в основе работы с коллекциями моего любимого языка. Правда, по результатам опроса нескольких знакомых разработчиков, оказалось что это не только моя проблема, очень многие вообще не задумываются, как работают коллекции в их любимых ЯП. А ведь используем мы их каждый день и не по разу. Так родилась идея этой статьи.
Читать дальше →
Total votes 191: ↑179 and ↓12 +167
Views47.4K
Comments 66

Дерево отрезков

Алгоритмы
Sandbox
Я расскажу о структуре под названием дерево отрезков и приведу его простую реализацию на языке С++. Эта структура весьма полезна в случаях, когда необходимо часто искать значение какой-то функции на отрезках линейного массива и иметь возможность быстро изменять значения группы подряд идущих элементов.
Типичный пример задачи на дерево отрезков:
Есть линейный массив, изначально заполненный некоторыми данными. Далее приходят 2 типа запросов:
1й тип — найти значение максимального элемента на отрезке массива [a..b].
2й тип — заменить iй элемент массива на x.
Возможен запрос «добавить х ко всем элементам на отрезке [a..b]», но в данной статье я его не рассматриваю.
С помощью дерева отрезков можно искать не только максимум чисел, но и любую функцию, удовлетворяющую свойству ассоциативности.
image
Это ограничение связано с тем, что используется предпросчет значений для некоторых отрезков.
Читать дальше →
Total votes 23: ↑14 and ↓9 +5
Views35.4K
Comments 6

Структуры данных в картинках. LinkedHashMap

Java
Привет Хабрачеловеки!

После затяжной паузы, я попробую продолжить визуализировать структуры данных в Java. В предыдущих статьях были замечены: ArrayList, LinkedList, HashMap. Сегодня заглянем внутрь к LinkedHashMap.



Из названия можно догадаться что данная структура является симбиозом связанных списков и хэш-мапов. Действительно, LinkedHashMap расширяет класс HashMap и реализует интерфейс Map, но что же в нем такого от связанных списков? Давайте будем разбираться.

Tell me more!
Total votes 28: ↑27 and ↓1 +26
Views206.1K
Comments 14

Двумерное дерево отрезков (с групповой модификацией элементов)

Алгоритмы
Sandbox

Предисловие и постановка задачи


Думаю, многие читатели этого сайта слышали о такой полезной структуре, как дерево отрезков. А если нет, то о нем в интернете можно отыскать множество интересного материала (здесь, статьи на Хабре: раз и два, google, наконец).
Здесь я разберу обобщение дерева отрезков на двумерный случай, причем (в отличие от этой статьи) рассмотрю реализацию дерева именно с поддержкой групповой модификации элементов.
Читать дальше →
Total votes 22: ↑20 and ↓2 +18
Views13.2K
Comments 11

Как работает ConcurrentHashMap

Java
В октябре на хабре появилась замечательная статья про работу HashMap. Продолжая данную тему, я собираюсь рассказать о реализации java.util.concurrent.ConcurrentHashMap.
Итак, как же появился ConcurrentHashMap, какие у него есть преимущества и как он был реализован.
Читать дальше →
Total votes 105: ↑100 and ↓5 +95
Views122K
Comments 14

Кучи. Часть 1. Биномиальная куча

Алгоритмы
Sandbox
Здравствуйте, Хабросообщество!

На хабре есть описание множества интересных структур данных, таких как деревья отрезков, дуча и т.п. Если Вам интересны сложные структуры данных, то добро пожаловать под кат!
Читать дальше →
Total votes 53: ↑45 and ↓8 +37
Views22.3K
Comments 14

Анализ данных. Приближенные множества

Python
Sandbox
Решил создать серию постов об анализе данных. Несколько лет работаю в этой (и как оказалось, весьма интересной) области информатики. Предлагаю Вашему вниманию анализ данных с точки зрения Теории приближенных множеств.
Читать дальше →
Total votes 28: ↑27 and ↓1 +26
Views8.1K
Comments 11

Sqrt-декомпозиция (корневая оптимизация)

Алгоритмы
Sandbox
Sqrt-декомпозиция — это метод, или структура данных, позволяющая в режиме онлайн проводить такие операции, как подсчет суммы на отрезке за image и обновление элемента за image. Существуют более эффективные структуры, такие как дерево фенвика или дерево отрезков, которые оба запроса обрабатывают за image. Однако я хочу рассказать про корневую оптимизацию, т.к. в этом методе заложена идея, применимая к задачам другого типа.


Постановка задачи

Пусть нам задан массив A[i], на который поступают запросы вида:
  • посчитать сумму на отрезке [L; R] (позже, мы поймем, что аналогично можно вычислять функции min, max, gcd и др.
  • добавить к элементу A[i], delta
Наивная реализация

Мы можем предрасчитать массив частичных сумм, а именно:
 for(int j = 0; j < i; j++) B[j] += A[i];
и тогда на запрос суммы [L; R], мы будем возвращать B[R]-B[L-1] за image. Однако на запрос изменения, потребует пересчета частичных сумм (содержащих этот элемент) и в худшем случае составит асимптотику порядка image, что не есть хорошо.
Читать дальше →
Total votes 41: ↑38 and ↓3 +35
Views13.9K
Comments 10

Структура Radix Tree для сжатия данных

C++Алгоритмы
Этот топик повествует об использовании Radix Tree на практическом примере. Radix Tree или дерево остатков — это структура данных, формируемая по принципу хранение значений в листовом узле. Промежуточные узлы представляют собой элемент конечного значения. Это может быть бит для чисел, символ для строк или цифра для номера, как в примере ниже. Приведенный алгоритм сжатия с использованием Radix Tree используется в реальной embeded системе, для хранения параметров телефонного файрвола.
Читать дальше →
Total votes 22: ↑19 and ↓3 +16
Views11.3K
Comments 5