Нахождение последнего элемента двоичной "кучи"

Обновленный ответ для достижения ваших целей с использованием CSS Grid inline-grid для создания встроенной сетки уровней:

grid-template-rows настроен на повторение максимум двух строк с 1fr каждый. [тысяча сто двадцать девять]

grid-template-columns настроен на повторение необходимого количества столбцов auto с шириной 35px.

grid-auto-flow установлен на column, чтобы иметь алгоритм автоматического размещения сетки для заполнения каждого столбца по очереди, добавляя новые столбцы по мере необходимости, сохраняя при этом максимум две строки.

grid-column-gap использовался для добавления отступов между столбцами для отображения тех же результатов, что и на предоставленных изображениях.

div {
  font-size: 30px;
  padding: 30px;
}

ul {
  display: inline-grid;
  grid-template-rows: repeat(2, 1fr);
  grid-template-columns: repeat(auto, 35px);
  grid-auto-flow: column;
  grid-column-gap: 10px;
  align-items: center;
  list-style: none;
  font-size: 10px;
  padding: 0;
  margin: 0;
  vertical-align: middle;
}

li {
  background: #9eff80;
  padding: 2px;
  opacity: 0.7;
}
I'd like to have a list with several columns
  • A list
  • like this
  • with unknown
  • number and items
  • or columns.
in the middle of other text.

Надеюсь, что это решит вашу проблему!


Если ваша цель - получить максимум из 3 пунктов columns, как показано на изображениях, я считаю, что свойство, которое вам нужно изменить, это:

column-width: 35px - columns: auto 3 , если вы хотите column-width каждого столбца установить на auto.

или

column-width: 35px - columns: 35px 3 , если вы хотите указать column-width для каждого столбца.

Это объяснение того, что делает свойство columns:

Свойство CSS columns устанавливает ширину столбца и количество столбцов элемента. - MDN - столбцы css

blockquote>

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

div {
  font-size: 30px;
  padding: 30px;
}

ul {
  display: inline-block;
  columns: auto 3;
  padding: 0;
  list-style: none;
  font-size: 10px;
  vertical-align: middle;
}

li {
  background: #9eff80;
  padding: 2px;
  opacity: 0.7;
}
I'd like to have a list with several columns
  • A list
  • like this
  • with unknown
  • number and items
  • or columns.
in the middle of other text.

Надеюсь, это поможет!

14
задан Marc Gravell 3 February 2011 в 09:58
поделиться

2 ответа

В основном заключенный в кавычки оператор относится к проблеме разрешения местоположения для вставки и удаления элементов данных в и от "кучи". Для поддержания "свойства формы" двоичной "кучи", самый низкий уровень "кучи" должен всегда быть заполнен от левого до права, не оставив пустых узлов. Для поддержания среднего числа O (1) вставка и времена удаления для двоичной "кучи" необходимо смочь определить местоположение для следующей вставки и местоположение последнего узла на самом низком уровне для использования для удаления корневого узла, обоих в постоянное время.

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

Для двоичной "кучи", сохраненной в древовидной структуре, эта информация не так очевидна, но потому что это - полное двоичное дерево, она может быть вычислена. Например, в полном двоичном дереве с 4 элементами, точка вставки всегда будет правильным ребенком покинутого ребенка корневого узла. Узел для использования для удаления всегда будет покинутым ребенком покинутого ребенка корневого узла. И для любого данного произвольного древовидного размера, дерево будет всегда иметь определенную форму с четко определенной вставкой и точками удаления. Поскольку дерево является "полным двоичным деревом" с определенной структурой для любого данного размера, очень возможно вычислить местоположение вставки/удаления в O (1) время. Однако выгода - то, что, даже когда Вы знаете, где это структурно, Вы понятия не имеете, где узел будет в памяти. Так, необходимо пересечь дерево для получения до данного узла, который является O (зарегистрируйте n), процесс, делающий всех, вставляет, и удаления минимум O (зарегистрируйте n), повреждая обычно желаемый O (1) поведение. Любой поиск ("в глубину", или некоторый другой) будет, по крайней мере, O (зарегистрируйте n), также из-за пересекающейся отмеченной проблемы и обычно O (n) из-за случайной природы полуотсортированной "кучи".

прием должен смочь и , вычисляют и ссылка те моменты вставки/удаления постоянного времени любой путем увеличения структуры данных ("распараллеливающий" дерево, как упоминание в статье Wikipedia) или использующий дополнительные указатели.

реализация, которую, кажется, мне является самым легким понять с низкой памятью и дополнительным кодированием наверху, должна просто использовать нормальную простую структуру двоичного дерева (использующий pRoot и Узел, определенный как [данные, родитель, pLeftChild, pRightChild]) и добавлять два дополнительных указателя (pInsert и pLastNode). pInsert и pLastNode будут и обновлены во время вставки и подпрограмм удаления для держания их в курсе, когда данные в структуре изменятся. Эта реализация дает O (1) доступ и к точке вставки и к последнему узлу структуры и должна позволить сохранение полного O (1) поведение и во вставке и удалениях. Стоимость реализации является двумя дополнительными указателями и некоторым незначительным дополнительным кодом в подпрограммах вставки/удаления (иначе, минимальный).

РЕДАКТИРОВАНИЕ : добавленный псевдокод для O (1) вставляет ()

, Вот псевдо код для подпрограммы вставки, которая является O (1) в среднем:

define Node = [T data, *pParent, *pLeft, *pRight]

void insert(T data)
{
    do_insertion( data );   // do insertion, update count of data items in tree

    # assume: pInsert points node location of the tree that where insertion just took place
    #   (aka, either shuffle only data during the insertion or keep pInsert updated during the bubble process)

    int N = this->CountOfDataItems + 1;     # note: CountOfDataItems will always be > 0 (and pRoot != null) after an insertion

    p = new Node( <null>, null, null, null);        // new empty node for the next insertion

    # update pInsert (three cases to handle)
    if ( int(log2(N)) == log2(N) )
        {# #1 - N is an exact power of two
        # O(log2(N))
        # tree is currently a full complete binary tree ("perfect")
        # ... must start a new lower level
        # traverse from pRoot down tree thru each pLeft until empty pLeft is found for insertion
        pInsert = pRoot;
        while (pInsert->pLeft != null) { pInsert = pInsert->pLeft; }    # log2(N) iterations
        p->pParent = pInsert;
        pInsert->pLeft = p;
        }
    else if ( isEven(N) )
        {# #2 - N is even (and NOT a power of 2)
        # O(1)
        p->pParent = pInsert->pParent;
        pInsert->pParent->pRight = p;
        }
    else 
        {# #3 - N is odd
        # O(1)
        p->pParent = pInsert->pParent->pParent->pRight;
        pInsert->pParent->pParent->pRight->pLeft = p;
        }
    pInsert = p;

    // update pLastNode
    // ... [similar process]
}

Так, вставьте (T), O (1) в среднем: точно O (1) во всех случаях кроме тех случаев, когда дерево должно быть увеличено одним уровнем, когда это - O (регистрируют N), который происходит каждый журнал N вставки (принимающий удаления). Добавление другого указателя (pLeftmostLeaf) могло сделать, вставляют () O (1) для всех случаев, и избегает возможного патологического случая переменной вставки & удаление в полном полном двоичном дереве. (Добавляющий pLeftmost оставлен как осуществление [это довольно легко].)

17
ответ дан 1 December 2019 в 08:53
поделиться

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

<час>

подход поиска в глубину (DFS) выше не предполагает знание общего количества узлов в дереве. Если эта информация доступна, то мы можем "увеличить масштаб" быстро к желаемому месту путем использования свойств полные двоичные деревья :

Позволяют N быть общим количеством узлов в дереве, и H быть высотой дерева.

Некоторые значения ( N, H) (1,0), (2,1), (3,1), (4,2)..., (7,2), (8, 3). Общая формула, связывающая эти два, , H = перекрывает [log2 ( N+1)] - 1. Теперь, учитывая только [1 121] N, мы хотим пересечь от корня до положения для нового узла в наименьшем количестве количества шагов, т.е. без любого "отслеживания в обратном порядке". Мы сначала вычисляем общее количество узлов M в идеальное двоичное дерево из высоты , H = перекрывает [log2 ( N+1)] - 1, который является M = 2^ ( H+1) - 1.

, Если N == M, то наше дерево прекрасно , и новый узел, должен быть добавлен на новом уровне. Это означает, что мы можем просто выполнить DFS (оставленный перед правом), пока мы не совершаем нападки первый лист; новый узел становится покинутым ребенком этого листа. Конец истории.

Однако, если N < M, затем существуют все еще вакансии на последнем уровне нашего дерева, и новый узел должен быть добавлен к крайнему левому свободному пятну. Количество узлов, которые уже являются на последнем уровне нашего дерева, просто ( N - 2^ H + 1). Это означает, что новый узел берет пятно X = ( N - 2^ H + 2) слева на последнем уровне.

Теперь, для получения там от корня необходимо будет сделать корректные повороты (L по сравнению с R) на каждом уровне так, чтобы Вы закончили в пятне X на последнем уровне. На практике Вы определили бы повороты с небольшим вычислением на каждом уровне. Однако я думаю, что следующая таблица показывает большое изображение и соответствующие шаблоны, не будучи испачканным в арифметике (можно распознать это как форму арифметика, кодирующая для равномерного распределения):

0 0 0 0 0 X 0 0 <--- represents the last level in our tree, X marks the spot!
          ^
L L L L R R R R <--- at level 0, proceed to the R child
L L R R L L R R <--- at level 1, proceed to the L child
L R L R L R L R <--- at level 2, proceed to the R child 
          ^                      (which is the position of the new node)
          this column tells us
          if we should proceed to the L or R child at each level

РЕДАКТИРОВАНИЕ: Включенный описание, как добраться до нового узла в самом коротком количестве шагов, предполагающих, что мы знаем общее количество узлов в дереве.

1
ответ дан 1 December 2019 в 08:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: