fix(guide): simplify directory structure

This commit is contained in:
Mrugesh Mohapatra
2018-10-16 21:26:13 +05:30
parent f989c28c52
commit da0df12ab7
35752 changed files with 0 additions and 317652 deletions

View File

@@ -0,0 +1,39 @@
---
title: Bloom Filter
localeTitle: Цветной фильтр
---
## Описание
Фильтр Bloom - это структура данных, аналогичная набору. Фильтр Bloom позволяет задать вопрос. _Этот элемент является членом набора?_ для быстрого ответа. Фильтр никогда не вернет _No,_ если элемент находится в наборе; но он может вернуть а,_ если элемент не находится в наборе. Это один из недостатков использования фильтра Bloom, есть вероятность получения ложных положительных результатов при проверке наличия элемента в наборе. Потенциал использования фильтра Bloom заключается в том, что добавление элемента в набор и проверка того, находится ли элемент в наборе, - это операция [O (n)](https://guide.freecodecamp.org/algorithms/algorithm-performance) с постоянным временем.
## пример
В следующем примере фильтр Bloom используется для создания списка друзей. Пример реализации использует три [функции хэширования](https://guide.freecodecamp.org/miscellaneous/hash-tables-and-hashing-functions) . Хеширующие функции поглощают строку (имя друга) и вычисляют единственное значение для строки в зависимости от количества пятен в фильтре Bloom.
Создайте фильтр как массив из 10 индексов. A `0` указывает, что в этом индексе нет элемента.
`[0,0,0,0,0,0,0,0,0,0]`
Пользователь добавляет Дэвида в список друзей. Строка ( `'David'` ) передается через несколько функций хеширования, которые возвращают `0` , `4` и `8` соответственно. Значения из хэш-функций используются для обновления массива фильтров по этим индексам.
Индексы фильтра обновляются с использованием этих хешированных значений. A `1` указывает, что элемент был добавлен в этот индекс.
`[1,0,0,0,1,0,0,0,1,0]`
Пользователь добавляет Рози в список друзей. Хеширующие функции возвращают `3` , `4` и `6` для `'Rosie'` . Индексы фильтра обновляются с использованием хешированных значений.
`[1,0,0,1,1,0,1,0,1,0]`
Есть чек, если Чак является членом списка друзей. Строка `'Chuck'` передается через хеширующие функции, возвращающие `1` , `3` и `6` . Когда массив фильтров проверяется по этим индексам, он возвращает `0` , `1` и `1` . Поскольку один индекс имеет значение `0` , Чак _определенно_ не входит в список.
Есть проверка, является ли Maja членом списка друзей. Строка `'Maja'` передается через хеширующие функции, возвращая `0` , `6` и `8` . Когда массив фильтров проверяется по этим индексам, он возвращает `1` , `1` и `1` . Поскольку все три индекса имеют значение `1` , Maja ожет_ быть уже членом списка. Это ложноположительный результат.
## Соображения
Bloom фильтры позволяют быстро искать , чтобы определить , является ли значение , озможно_ , состоит из набора или _определенно_ не является членом множества. Чем больше элементов, добавленных в фильтр Блума, тем больше вероятность получения ложных положительных результатов при проверке того, является ли элемент членом набора. Один из способов уменьшить скорость ложноположительных результатов - увеличить размер массива. Хотя это компромисс, потому что чем больше массив, тем большую память он займет. Необходимо определить приемлемую скорость ложноположительных результатов для заданного размера массива.
## Дальнейшее чтение
[Средний алгоритм публикации](https://blog.medium.com/what-are-bloom-filters-1ec2a50c68ff)
[Википедия на Bloom фильтры](https://en.wikipedia.org/wiki/Bloom_filter)

View File

@@ -0,0 +1,215 @@
---
title: Dictionaries
localeTitle: Словари
---
## Словари
Предположим, у нас есть однородный список. Мы хотим подсчитать, сколько раз каждый элемент появляется в списке. Как мы можем это сделать, не используя встроенные методы Python, такие как счетчик или счетчик из модуля коллекций Python? Поиск в Google «Как подсчитать появление элемента в списке?» вернет ответы стека переполнения, указывая на метод подсчета и модуль коллекций, но в целях обучения попробуем решить проблему без использования этих инструментов.
Вот список, с которым мы будем работать:
```python
ice_cream = ["strawberry",
"vanilla",
"vanilla",
"chocolate",
"chocolate",
"chocolate",
"banana",
"rum raisin",
"banana"]
```
Этот код, используя вложенные для циклов, дает правильный ответ, сохраняя ответ в списке «count»:
```python
count = []
for flavor in ice_cream:
found = False
for entry in count:
if entry[0] == flavor:
entry[1] += 1
found = True
if not found:
count.append([flavor, 1])
# Print.
for (entry, total) in count:
print (entry, total)
```
Хотя этот код дает правильный ответ, в этом есть две вещи. Во-первых, это сложно. Чем больше вложенных циклов содержит программа, тем труднее понять, исправить и расширить. Более того, он неэффективен. Это не может быть проблемой в этом небольшом примере, но представьте себе список с тысячами или миллионами элементов. Сканирование списка записей каждый раз, когда мы делаем наблюдение, занимало бы очень, очень долгое время, независимо от того, насколько быстро компьютер. Эта тема более подробно рассматривается при изучении таких тем, как большая нотация O и сравнение алгоритмов поиска и сортировки.
Лучшим ответом является использование другой структуры данных, известной как **словарь** или **карта** . Эта структура данных представляет собой еупорядоченный, изменяемый_ набор пар _ключ / значение_ . Подумайте о словаре, таком как телефонная книга, где ключ - это имя человека, а значение - номер телефона. Ключи в словаре образуют набор, то есть они могут появляться только один раз, и их нельзя изменить (они неизменяемы), хотя значения, связанные с ключом, могут быть изменены.
Словари создаются путем ввода пар ключ / значение внутри фигурных скобок. Чтобы получить значение, связанное с ключом, вы кладете ключ в квадратные скобки.
Вот несколько примеров кода:
```python
ice_cream = {'chocolate' : 3, 'strawberry' : 1}
print (ice_cream)
>> {'chocolate' : 3, 'strawberry' : 1}
print (ice_cream['strawberry'])
>> 1
```
Чтобы проверить, находится ли ключ в словаре, используйте k в d:
```python
ice_cream = {'chocolate' : 3, 'strawberry' : 1}
if 'chocolate' in ice_cream:
print ('chocolate is in the list')
...
del ice_cream['chocolate']
if 'chocolate' in ice_cream:
print ('oops: why is chocolate still there?')
```
**Обновление и членство** Чтобы обновить словари, просто присвойте значение ключу. Если ключ уже находится в словаре, это изменяет значение, связанное с ним.
Если ключ отсутствовал, он добавляется вместе со значением:
```python
ice_cream = {}
ice_cream['chocolate'] = 33
ice_cream['vanilla'] = 999 # oops
print (ice_cream)
>> {'chocolate' : 33, vanilla' : 999}
ice_cream['vanilla'] = 9
print (ice_cream)
>> {'chocolate' : 33, vanilla' : 9}
```
Используйте _del d \[k\]_ , чтобы удалить запись из словаря, где _d_ - имя словаря, а _k_ - удаляемый ключ. Можно удалить только те записи, которые присутствуют; попытка удалить тот, который не существует, вызывает ошибку:
```python
ice_cream = {'chocolate' : 33, vanilla' : 9}
del ice_cream['chocolate']
print (ice_cream)
>> {'vanilla' : 9}
del ice_cream['strawberry']
>> Traceback (most recent call last):
File "<stdin>", line 5, in <module>
KeyError: 'strawberry'
```
**Loops** Так как словари представляют собой коллекции (вместе со списками, кортежами и наборами), мы собираемся содержание. Мы делаем это с циклом for, который поочередно присваивает каждому из ключей словаря переменную цикла:
```python
ice_cream = {'chocolate' : 183,
'vanilla' : 71,
'strawberry' : 63,
'banana', 1}
for flavor in ice_cream:
print (flavor, ice_cream[flavor])
>> 'banana' 1
'vanilla' 71
'chocolate' 183
'strawberry' 63
```
Как и в случае с установленными элементами, Python перебирает записи в словаре в произвольном порядке. Нет гарантии, что они будут отображаться в алфавитном порядке или в порядке, они были добавлены в словарь. Обратите внимание, кстати, что переплетение словарей немного отличается от циклов над списками. Когда Python перебирает список, значения в списке присваиваются переменной цикла. Когда он перебирает словарь, с другой стороны, он назначает ключи. Дизайнеры Python решили сделать это, потому что:
* петля над индексами списка не очень интересна, так как программа всегда будет получать последовательность 0, 1, 2, ...; а также
* гораздо проще перейти от словарного ключа к соответствующему значению чем принимать значение и находить соответствующий ключ.
**Методы словаря** Словари - это объекты, как и списки, кортежи и наборы. Несколько общих методов словаря:
* _d.clear ()_ - очистить словарь
* _d.get (x, 99)_ - Возвращает значение, связанное с ключом, или значение по умолчанию, если ключ отсутствует.
* _d.keys ()_ - клавиши возврата
* _d.items ()_ - возвращает список пар ключей, значений
* _d.values ()_ - возвращает значения в виде списка, значения могут быть не уникальными
* _d.update ()_ - обновить словарь с содержимым другого
Одним распространенным применением элементов является цикл над ключами и значениями в словаре вместе: for (key, value) в словаре.items (): ... делать что-то с ключом и ценностью ...
Это неэффективно для больших словарей, поскольку items () фактически создает список пар (ключ, значение). Аналогичный метод, называемый _iteritems (),_ передает эти пары один за другим по требованию: для (ключ, значение) в словаре.iteritems (): ... делать что-то с ключом и ценностью ...
Вернемся к исходному примеру - как подсчитать количество элементов в списке ice\_cream с помощью словаря?
```python
# Count all the flavors.
ice_cream = ["strawberry",
"vanilla",
"vanilla",
"chocolate",
"chocolate",
"chocolate",
"banana",
"rum raisin",
"banana"]
count = {}
for flavor in ice_cream:
if flavor in count:
count[flavor] = count[flavor] + 1
else:
count[flavor] = 1
# Print.
for b in count:
print (b, count[b])
```
Для этого мы создаем словарь, который изначально пуст. Каждый раз, когда мы просматриваем список ice\_cream, мы проверяем чтобы узнать, находится ли этот вкус уже в словаре count. Если это так, добавим его к его счету. Если это не так, мы добавляем имя в словарь со значением 1.
Мы можем немного сократить эту программу, используя метод _dict.get ()_ . Это возвращает значение, связанное с ключом или некоторым значением по умолчанию, которое мы предоставляем. В этом случае мы получаем либо количество раз, когда мы уже видели вкус, либо ноль, добавляем его к тому, какое значение возвращает метод, и сохраняем его в словаре:
```python
# Count all the flavors.
count = {}
for flavor in ice_cream:
count[flavor] = count.get(flavor, 0) + 1
# Print.
keys = count.keys()
keys.sort()
for b in keys:
print (b, count[b])
# Print.
for key in sorted(count):
print (key, count[key])
```
Обратите внимание, что мы используем два разных способа печати ключа и значения: один использует сортированный метод Python, а другой - нет.
Если бы мы хотели напечатать ароматы по порядку частоты, нам нужно **инвертировать словарь** . Это означает, что нам нужно использовать значения как ключи, а ключи - как значения. Поскольку нет никакой гарантии, что значения уникальны, нам нужно предпринять шаги, чтобы избежать _столкновений_ .
Решение состоит в том, чтобы использовать какую-то коллекцию, такую ​​как список, для хранения значений инвертированного словаря. Если мы пройдем по этому маршруту, обратный словарь, показанный ранее, будет {1: \['a', 'b', 'c'\]}. Вот программа, которая сделает то, что мы хотим:
```python
ice_cream = ["strawberry",
"vanilla",
"vanilla",
"chocolate",
"chocolate",
"chocolate",
"banana",
"rum raisin",
"banana"]
# Count all the flavors.
count = {}
for flavor in ice_cream:
count[flavor] = count.get(flavor, 0) + 1
# Invert the dictionary.
freq = {}
for (flavor, times) in count.items():
if times in freq:
freq[times].append(flavor)
else:
freq[times] = [flavor]
# Print.
for key in freq:
for flavor in sorted(freq[key]):
print (key,":", " ", flavor)
```
#### Дополнительная информация:

View File

@@ -0,0 +1,47 @@
---
title: Graphs
localeTitle: диаграммы
---
## диаграммы
График - это структура данных, которую вы можете использовать для решения проблем маршрутизации, таких как «Связаны ли эти два компонента?» и «Каков самый короткий путь от точки a до b?»
Граф состоит из узлов и ребер. Узел (т.е. вершина) является объектом вашего графика. Узел может содержать информацию, такую ​​как имя узла и к каким кромкам он привязан. Кромка - это связь, соединяющая два узла. Край может содержать информацию, такую ​​как вес края. Если два узла соединены ребром, они являются соседями (то есть смежными).
В зависимости от проблемы вы можете использовать двусторонние (неориентированные) или односторонние (направленные) ребра. Если у вас есть неориентированный край от a до b, есть также путь от b до a. Если у вас есть направленное ребро от a до b, не обязательно будет край от b до a.
Графики можно использовать для формулирования таких ситуаций, как:
* Географические карты
* Каждый город в вашей стране является узлом
* Если два города связаны дорогой, между ними есть край \* Дороги могут быть одно- или двухсторонними (как направленными, так и неориентированными краями) \* вес может быть длиной дороги
* Поток воды
* Каждый шлюз является узлом
* Каждый канал - это край
* вода будет течь только в одном направлении, так что края направлены
* вес может быть максимальной водной емкостью потока
Пример: график, который имеет узлы столиц северных стран и как (неориентированные) края, расстояние до городов, связанных прямой дорогой.
```
. +---------+
. |Reykjavik|
. +---------+
.
.
. 529 km +---------+ 1760 km +--------+
. +------------+|Stockholm|+---------+|Helsinki|
. | +---------+ +--------+
. + +
. +----+ 1991 km |
. |Oslo|+-------------------------------------+
. +----+
. +----------+
. |Copenhagen|
. +----------+
```
#### Дополнительная информация:
[Первый поиск Breadth (BFS)](https://github.com/freecodecamp/guides/tree/master/src/pages/algorithms/graph-algorithms/breadth-first-search/index.md)
[Глубина первого поиска (DFS)](https://github.com/freecodecamp/guides/tree/master/src/pages/algorithms/graph-algorithms/depth-first-search/index.md)

View File

@@ -0,0 +1,127 @@
---
title: Hash Tables
localeTitle: Хэш-таблицы
---
## Хэш-таблицы
Хэш-таблица (или хэш-карта) представляет собой структуру данных, которая может сопоставлять ключи с значениями. В хеш-таблице используется хэш-функция для вычисления индекса в массив ведер, из которых можно найти нужные значения. Временная сложность хорошо определенной функции Хэша может быть O (1).
Хэш-таблица (хэш-карта) представляет собой структуру данных, которая реализует абстрактный тип абстрактных массивов, структуру, которая может сопоставлять ключи со значениями. Хэш-таблица использует хеш-функцию для вычисления индекса в массив ведер или слотов, из которого можно найти желаемое значение.
![пример хеш-таблицы](https://github.com/TomerPacific/fccGuideImages/blob/master/315px-Hash_table_3_1_1_0_1_0_0_SP.svg.png?raw=true)
Некоторые важные свойства Hash Table - 1) Значения не сохраняются в отсортированном порядке. 2) В хэш-таблице нужно также обрабатывать потенциальные столкновения. Это часто делается путем цепочки, что означает создание связанного списка всех значений, ключи которых сопоставляются с определенным индексом.
Реализация таблицы хешей
Хэш-таблица традиционно реализуется с массивом связанных списков. Когда мы хотим вставить пару ключ / значение, мы сопоставляем ключ с индексом в массиве с помощью хэш-функции. Затем значение вставляется в связанный список в этой позиции.
Идея хеширования состоит в том, чтобы распределять записи (пары ключ / значение) по массиву ведер. Учитывая ключ, алгоритм вычисляет индекс, который указывает, где можно найти запись:
```
index = f(key, array_size)
```
Часто это делается в два этапа:
```
hash = hashfunc(key)
index = hash % array_size
```
В этом методе хэш не зависит от размера массива, а затем сводится к индексу (число от 0 до array\_size - 1) с использованием оператора modulo (%).
Рассмотрим строку S. Вам необходимо подсчитать частоту всех символов в этой строке.
```
string S = “ababcd”
```
Самый простой способ сделать это - перебрать все возможные символы и подсчитать их частоту один за другим. Сложность времени этого подхода O (26 \* N), где N - размер строки, и имеется 26 возможных символов.
```
void countFre(string S)
{
for(char c = 'a';c <= 'z';++c)
{
int frequency = 0;
for(int i = 0;i < S.length();++i)
if(S[i] == c)
frequency++;
cout << c << ' ' << frequency << endl;
}
}
```
Вывод
```
a 2
b 2
c 1
d 1
e 0
f 0
z 0
```
Давайте применим хеширование к этой проблеме. Возьмите частоту массива размером 26 и хэш 26 символов с индексами массива с помощью хэш-функции. Затем перебираем строку и увеличиваем значение в частоте по соответствующему индексу для каждого символа. Сложность этого подхода - O (N), где N - размер строки.
```
int Frequency[26];
int hashFunc(char c)
{
return (c - 'a');
}
void countFre(string S)
{
for(int i = 0;i < S.length();++i)
{
int index = hashFunc(S[i]);
Frequency[index]++;
}
for(int i = 0;i < 26;++i)
cout << (char)(i+'a') << ' ' << Frequency[i] << endl;
}
```
Вывод
```
a 2
b 2
c 1
d 1
e 0
f 0
z 0
```
### Хэш-столкновение
Когда вы используете хэш-карту, вы должны предположить, что хеш-коллизии неизбежны, так как вы будете использовать хэш-карту, которая значительно меньше по размеру, чем объем данных, которые у вас есть. Двумя основными подходами к решению этих столкновений являются цепочка и открытая адресация.
#### Цепной
Один из способов разрешения хеш-коллизий - использование цепочки. Это означает, что для каждого сопоставления значений ключа в хэш-таблице поле значения не будет содержать только одну ячейку данных, а скорее связанный список данных. В примере, показанном на рисунке ниже, вы можете видеть, что Сандра Ди добавляется в качестве другого элемента к ключу 152 после Джона Смита.
![пример цепочки в хеш-таблице](https://github.com/TomerPacific/fccGuideImages/blob/master/620px-Hash_table_5_0_1_1_1_1_0_LL.svg.png?raw=true)
Основным препятствием для цепочки является увеличение временной сложности. Это означает, что вместо свойств O (1) регулярной хеш-таблицы каждое действие будет занимать больше времени, поскольку нам нужно пересечь связанный список.
#### Открытая адресация
Другой способ разрешения хэш-коллизий - использовать открытую адресацию. В этом методе, когда значение отображается на уже занятый ключ, вы перемещаетесь по соседним клавишам хэш-таблицы определенным образом, пока не найдете ключ с пустым значением. В примере, показанном на изображении ниже, Сандра Ди отображается на ключ 153, хотя ее значение должно быть отображено на 152.
![пример открытой адресации в хеш-таблице](https://github.com/TomerPacific/fccGuideImages/blob/master/380px-Hash_table_5_0_1_1_1_1_0_SP.svg.png?raw=true)
Основная проблема открытой адресации заключается в том, что, когда нужно искать значения, они могут оказаться не такими, какие вы ожидаете от них (сопоставление ключей). Поэтому вам нужно пройти части хэш-таблицы, чтобы найти нужное вам значение, что привело к увеличению временной сложности.
#### Сложность времени
Очень важно отметить, что хеш-таблицы амортизируют постоянную сложность, т. Е. В среднем случае сложность будет равна O (1). В худшем случае, если слишком много элементов было хэшировано в один и тот же ключ, это может иметь временную сложность O (n).
### Дополнительная информация:
[Дополнительная информация о Hash Tables - Wiki](https://en.wikipedia.org/wiki/Hash_table) [Сравнение между таблицей хэшей и STL-картой](http://www.geeksforgeeks.org/hash-table-vs-stl-map/)
#### Источник
[Основы Hash Tables - HackerEarth](https://www.hackerearth.com/practice/data-structures/hash-tables/basics-of-hash-tables/tutorial/)

View File

@@ -0,0 +1,20 @@
---
title: Data Structures
localeTitle: Структуры данных
---
## Структуры данных
Структура данных - это способ сбора и организации данных таким образом, чтобы мы могли эффективно выполнять эти данные. Структуры данных - это представление элементов данных в терминах некоторых отношений для лучшей организации и хранения. Например, у нас есть имя игрока данных «Virat» и возраст 26. Здесь «Virat» имеет тип данных String, а 26 - целочисленный тип данных.
Мы можем организовать эти данные как запись, такую ​​как запись игрока. Теперь мы можем собирать и хранить записи игрока в файле или базе данных в виде структуры данных. Например: «Dhoni» 30, «Гамбир» 31, «Sehwag» 33
На простом языке Data Structures представляют собой структуры, запрограммированные для хранения упорядоченных данных, так что различные операции могут выполняться на нем легко. Он представляет собой знание данных, которые должны быть организованы в памяти. Он должен быть разработан и реализован таким образом, чтобы он уменьшал сложность и повышал эффективность.
В памяти компьютера, то есть ОЗУ, различные структуры данных создаются как стек, очередь, список ссылок, кучи и т. Д. В соответствии с требованием программы, чтобы эффективно использовать память.
#### Дополнительная информация:
* [Структуры данных](http://www.studytonight.com/data-structures/introduction-to-data-structures)
* [Выродка для Geek](http://www.geeksforgeeks.org/data-structures/)
* [Точки обучения](https://www.tutorialspoint.com/data_structures_algorithms/data_structure_overview.htm)
* [Структуры данных](http://www.studytonight.com/data-structures/introduction-to-data-structures)

View File

@@ -0,0 +1,347 @@
---
title: Linked Lists
localeTitle: Связанные списки
---
## Связанные списки
#### Связанный список - это простая структура данных с _линейным доступом_ .
Связанный список представляет собой простую структуру данных, но его можно использовать для реализации более сложных структур данных, таких как очереди, стеки и т. Д. Существует три типа связанных списков:
1. Простой связанный список
2. Дважды связанный список (или двойной объединенный список)
3. Циклические связанные списки (кольцевой буфер)
Связанный список | (Вступление) Подобно массивам, Linked List представляет собой линейную структуру данных. В отличие от массивов элементы связанного списка не сохраняются в смежном местоположении; элементы связаны с помощью указателей или как в примере с использованием Javascript, ссылки на следующий узел.
Если вы хотите понять Linked Lists, это поможет понять **Массивы** .
Для повторения массив традиционно представляет собой **статическую** **линейную** структуру данных, которая поддерживает постоянный случайный доступ во времени. Вставки и удаления не всегда являются постоянными.
Преимущества по сравнению с массивами 1) Динамический размер 2) Простота вставки / удаления
\`\` \` static = размер, зафиксированный во время создания linear = хранится линейно в памяти как единый блок
```
#### Arrays have the following disadvantages:-
1. Arrays are static structures and therefore cannot be easily extended or reduced to fit the data set.
2. Arrays are also expensive to maintain new insertions and deletions.
Linked Lists address some of the limitations of arrays. Unlike an array, where all the elements are stored in a contiguous block of memory, in a linked list each element is a separate object and has a **link** to the next element in sequence. This allows a linked list to start with space for only one element, and grow to accomodate an arbitrary number of elements by allocating memory as and when needed.
Deleting elements is also simply handled by manipulating links.
Once you understand the Simple Linked List (which from here on will be referred as **'List'**), you can move on to the Doubly Linked List.
A List as illustrated below is made up of the following components:-
```
```
head
|
|
+---+---+ +---+---+ +----+------+
| 1 | o----->| 2 | o-----> | 3 | φ |
+---+---+ +---+---+ +----+------+
|
|
tail
```
```
| Node | Significance |
| ----------|-------------|
| HEAD | Beginning of the List|
| Node(s) | Dynamically allocated self-referential block contain 1 Data element and a link to the next node |
| TAIL | End of the List |
Most common operations available on List are,
1. AddFirst - Inserts an element at the front of the List.
2. AddLast - Inserts an element at the tail of the List.
3. InsertAfter - Inserts an element after an existing element in the List.
4. InsertBefore - Inserts an element before an existing element in the List.
5. Remove - Remove an existing element from the List.
6. Access / Peek - Access an existing element from the List.
7. Size / Count - Returns the number of elements currently present in the List.
8. IsEmpty - Check whether the List is empty or not.
#### Implementation of a Simple Linked List in C++
```
CPP
# включают
использование пространства имен std;
struct Number { int num; struct Number \* tail; };
typedef struct Number N;
Список классов { частный: N _головка,_ конец; int count;
```
public:
void display();
void insertBefore(int);
List();
```
};
Список :: Список () { голова = NULL; конец = NULL; кол = 0; }
void List :: insertBefore (int data) { N \* узел; node = new N; node-> Num = данные; node-> хвост = NULL;
```
if(!head){
head=end=node;
}
else{
node->tail=head;
head=node;
}
count++;
```
}
void List :: display () { cout << "Число узлов в списке =" << count << endl; N \* узел; Узел = головы; в то время как (узел) {
```
cout<<node->num<<endl;
node=node->tail;
}
```
} int main () { Список l1;
```
l1.insertBefore(10);
l1.insertBefore(20);
l1.insertBefore(30);
l1.insertBefore(40);
l1.insertBefore(50);
l1.display();
return 0;
```
}
```
#### OUTPUT
```
Количество узлов в списке = 5 50 40 30 20 10
```
#### Explanation
```
CPP
struct Number { int num; struct Number \* tail;
};
```
Declaration of a structure(node) with 2 data members
* `num` holds the integer data value
* `*tail` pointer points to the next node in the List
```
CPP Список классов { частный: N _головка,_ конец; int count;
```
public:
void display();
void insertBefore(int);
List();
```
};
```
The List class declares the Linked List.
* `*head` points to the first node in the List
* `*end` points to the last node in the List
* `count` holds the value for number of nodes in the list
* `display()` is used to print the complete list on the console
* `insertBefore()` is used to insert a new node
* `List()` is a defualt constructor
```
CPP Список :: Список () { голова = NULL; конец = NULL; кол = 0; }
```
The default constructor is used to initialize the data members of the List class with default values
```
CPP void List :: insertBefore (int data) { N \* узел; node = new N; node-> Num = данные; node-> хвост = NULL;
```
if(!head){
head=end=node;
}
else{
node->tail=head;
head=node;
}
count++;
```
}
```
* A new node is created.
* `num` is assigned the value of `data`.
* `tail` is pointing to Null.
* The `if(!head)` condition is true only when there are no elements in the List.
* When this is the case, `head` and `end` are both pointing to the newly created node.
* Control will move to the `else` section, when there is at least one node in the list.
* In this case, `tail` pointer in the newly created node is made to point to the `head`(first) node.
* The `head` pointer then points to the newly created node to make it the first node in the list.
* `count` is incremented by 1 as each new node is added.
```
CPP void List :: display () { N \* узел; Узел = головы; в то время как (узел) { соиЬ < Num <
```
The display function is used to run through the list and print the total number of nodes and values of `num` on the console.
#### Applications
* Base Data Structure for Vector, Array, Queue, Stack, etc
* Polynomial Representation
* Ring Buffer
Drawbacks:
1) Random access is not allowed. We have to access elements sequentially starting from the first node. So we cannot do binary search with linked lists.
2) Extra memory space for a pointer is required with each element of the list
Types:
1) (Singly) linked lists contain nodes which have a data field as well as a 'next' field, which points to the next node in line of nodes. Operations that can be performed on singly linked lists include insertion, deletion and traversal.
2) (Doubly) In a 'doubly linked list', each node contains, besides the next-node link, a second link field pointing to the 'previous' node in the sequence. The two links may be called 'forward('s') and 'backwards', or 'next' and 'prev'('previous').
Example in Javascript:
```
function LinkedList () { this.head = null; this.tail = null; }
```
// Node has three properties value, next, prev
function Node (value, next, prev) {
this.value = value;
// A 'pointer' referencing to the next Node (if present) otherwise null
this.next = next;
// A 'pointer' referencing the previous Node, otherwise null
this.prev = prev;
}
LinkedList.prototype.addToHead = function(value) {
let newNode = new Node(value, this.head, null);
if (this.head) this.head.prev = newNode;
else this.tail = newNode;
this.head = newNode;
}
```
```
Now Execute code
```
пусть LL = новый LinkedList ();
```
LL.addToHead(100);
LL.addToHead(200);
console.log(LL);
```
```
Representation in C:
A linked list is represented by a pointer to the first node of the linked list. The first node is called head. If the linked list is empty, then value of head is NULL.
Each node in a list consists of at least two parts:
1) data
2) pointer to the next node
In C, we can represent a node using structures. Below is an example of a linked list node with an integer data.
In Java, LinkedList can be represented as a class and a Node as a separate class. The LinkedList class contains a reference of Node class type
```
С // Связанный узел списка struct Node { int данные; struct Node \* next; };
```
# Linked List with three elements
```
с // Простая программа C для введения // связанный список
# включают
# включают
struct Node { int данные; struct Node \* next; };
// Программа для создания простого связанного // список с 3 узлами int main () { struct Node \* head = NULL; struct Node \* second = NULL; struct Node \* third = NULL;
// выделяем 3 узла в куче
head = (struct Node _) malloc (sizeof (struct Node)); second = (struct Node_ ) malloc (sizeof (struct Node)); third = (struct Node \*) malloc (sizeof (struct Node));
/ \* Три блока распределены динамически. У нас есть указатели на эти три блока, как первый, второй и третий
второй третья глава | | | | | | + --- + ----- + + ---- + ---- + + ---- + ---- + | # | # | | # | # | | # | # | + --- + ----- + + ---- + ---- + + ---- + ---- +
\# представляет любое случайное значение. Данные случайны, потому что мы еще ничего не назначили \* /
head-> data = 1; // назначение данных в первом узле head-> next = second; // Связывание первого узла со вторым узлом
/ \* данные были присвоены части данных первого блока (блок заостренный головой). И следующий указатель первого блока указывает на второй. Поэтому они оба связаны.
```
head second third
| | |
| | |
+---+---+ +----+----+ +-----+----+
| 1 | o----->| # | # | | # | # |
+---+---+ +----+----+ +-----+----+
```
\* /
second-> data = 2; // присвоение данных второму узлу second-> next = third; // Связывание второго узла с третьим узлом
/ \* данные были привязаны к части данных второго блока (блок, на который указывает второй). А следующий указатель второго блока указывает на третий блок.
Таким образом, все три блока связаны.
```
head second third
| | |
| | |
+---+---+ +---+---+ +----+----+
| 1 | o----->| 2 | o-----> | # | # |
+---+---+ +---+---+ +----+----+ */
```
третье -> данные = 3; // присвоение данных третьему узлу third-> next = NULL;
/ \* данные были привязаны к части данных третьего блока (фиксированный блок третий). И следующий указатель третьего блока сделан NULL для указания что связанный список здесь завершен.
```
We have the linked list ready.
head
|
|
+---+---+ +---+---+ +----+------+
| 1 | o----->| 2 | o-----> | 3 | NULL |
+---+---+ +---+---+ +----+------+
Note that only head is sufficient to represent the whole list. We can
traverse the complete list by following next pointers. */
```
return 0; } \`\` \`
#### Дополнительная информация:
* [Введение в связанные списки](http://www.geeksforgeeks.org/linked-list-set-1-introduction/)
* [Связанные списки (видео на YouTube)](https://www.youtube.com/watch?v=njTh_OwMljA)

View File

@@ -0,0 +1,46 @@
---
title: Queues
localeTitle: фрак
---
## Очереди
Очередь - структура данных First In First Out (FIFO). Многие алгоритмы используют очереди в своих ядрах для повышения производительности.
Очередь - один из основных абстрактных типов данных (ADT). Он похож на очереди, которые мы имеем в фильмах или супермаркетах. Первый человек, который должен прибыть, будет подан в первую очередь? Аналогично, первый элемент, который нужно вставить, будет удален первым. Существует несколько типов очередей, таких как,
1. Простая очередь (или очередь)
2. Круговая очередь
3. Очередь приоритетов
4. Dequeue (Double Ended Queue)
Если вы можете понять простую очередь (которая здесь будет упоминаться как «Очередь»), то все остальные будут такими же легкими, с небольшими изменениями.
Наиболее распространенными операциями, доступными в очереди, являются:
1. Добавить / Предложение - Вставляет элемент в конец очереди.
2. Удалить / Опрос. Удалите элемент с начала очереди.
3. Peek - возвращает элемент в начале очереди, но не удаляет его.
4. Size / Count - Возвращает количество элементов, присутствующих в очереди.
5. IsEmpty - Проверьте, пуста ли очередь или нет.
Реализация очереди возможна с использованием массивов или связанных списков. Ниже приведена простая реализация массива структуры данных очереди с ее наиболее распространенными операциями.
\`\` \`JavaScript
var Queue = function () { var queue = \[\]; var front = 0; var back = 0; вернуть { isEmpty: function () { return front> = назад || queue.length === 0; }, add: function (elem) { / \* Вы также можете сделать queue.push (elem) в JavaScript. Так они делают это на других языках \* / queue \[назад ++\] = elem; }, remove: function () { if (! this.isEmpty ()) { очередь возврата \[front ++\]; // или queue.shift () } else { throw new Error («Очередь пуста»); } }, peek: function () { if (! this.isEmpty ()) { очередь возврата \[фронт\]; } } } };
var queue = new Queue (); console.log (queue.isEmpty ()); // правда queue.add (1); queue.add (2); console.log (queue.remove ()); // 1 console.log (queue.peek ()); // 2 console.log (queue.remove ()); // 2 console.log (queue.remove ()); // исключение \`\` \`
#### Приложения
* моделирование
* Планирование (планирование работы, планирование диска)
* Управление совместными ресурсами
* Буфер клавиатуры
* Поиск в ширину
* Управлять перегрузками в сети
#### Дополнительная информация:
* [Дополнительная информация о очередях - GeeksForGeeks](http://www.geeksforgeeks.org/queue-data-structure/)
* [Решать проблемы с помощью очередей - Hackerrank](https://www.hackerrank.com/domains/data-structures/queues)
* [HackerRank стеки и очереди видео](https://www.youtube.com/watch?v=wjI1WNcIntg)

View File

@@ -0,0 +1,115 @@
---
title: Stacks
localeTitle: Стеки
---
## Стеки
Стеки представляют собой структуру данных First In Last Out (FILO). Это линейная структура данных.
Вы можете представить себе стопку, как тарелки были организованы в ресторане "шведский стол". Вы можете выбрать только тарелку сверху, иначе стек рухнет. Как правило, последний элемент, который нужно вставить, будет удален первым.
Некоторые основные операции стека:
1. Push - Вставляет элемент вверху стека.
2. Pop - Удаляет элемент в верхней части стека.
3. isEmpty - проверить, пуст ли пуст или нет.
4. Размер. Возвращает количество элементов в стеке. (Все операции могут выполняться в O (1) раз)
Реализация стека возможна с использованием массивов или связанных списков. Ниже приведена простая реализация массива структуры данных стека с наиболее распространенными операциями.
```C++
//Stack implementation using array in C++
//You can also include<stack> and then use the C++ STL Library stack class.
#include <bits/stdc++.h>
using namespace std;
class Stack {
int t;
int arr[MaxN];
public:
Stack() {
t = 0;
}
int size() {
return t;
}
bool isEmpty() {
return t < 1;
}
int top() {
return arr[t];
}
void push(int x) {
if (++t >= MaxN) {
cout << "Stack is full" << '\n';
return;
}
arr[t] = x;
}
void pop() {
arr[t--] = 0;
}
};
int main() {
Stack st;
st.push(4);
st.push(3);
st.push(5);
while (!st.isEmpty()) {
cout << st.size() << ' ' << st.top() << '\n';
st.pop();
}
return 0;
}
```
#### Использование массивов в виде стеков
В некоторых языках программирования массив имеет функциональность стека, что позволяет разработчику выполнять операции **push** и **pop** без необходимости создания структуры данных пользовательского стека.
Например, массив в JavaScript имеет методы **push** и **pop,** позволяющие легко реализовать функциональность стека в приложении.
```js
stack = [];
let i = 0;
while(i < 5)
stack.push(i++);
while(stack.length) {
stack.pop();
}
```
Список в Python также может выполнять функции стека в приложении. Вместо **push** можно использовать метод **append** .
```python
stack = []
for i in range(5):
stack.append(i)
while len(stack):
stack.pop()
```
#### Приложения
* Поверните рекурсию в цикл.
* Функции Redo-Undo.
* Судоку-решатель
* Глубина первого поиска.
* Обходы деревьев
* Выражение Infix -> Префикс / Постфиксное выражение
* Действительные скобки
#### Дополнительная информация:
* [Дополнительная информация о Stacks - GeeksForGeeks](http://www.geeksforgeeks.org/stack-data-structure/)
* [Стек - Википедия](https://en.wikipedia.org/wiki/Stack_(abstract_data_type)
* [Башня Ханой Проблема и то, как в решении используются стеки и рекурсии](https://en.wikipedia.org/wiki/Tower_of_Hanoi)
* [HackerRank стеки и очереди видео](https://www.youtube.com/watch?v=wjI1WNcIntg)

View File

@@ -0,0 +1,72 @@
---
title: Trees
localeTitle: деревья
---
# деревья
Структура данных дерева может быть определена рекурсивно (локально) в виде набора узлов (начиная с корневого узла), где каждый узел представляет собой структуру данных, состоящую из значения, вместе со списком ссылок на узлы («дети») , с ограничениями, которые не дублируются ссылкой, и ни один не указывает на корень. Дерево без узлов называется нулевым или пустым деревом.
Бинарное дерево представляет собой нелинейную структуру данных, состоящую из узлов, где каждый узел имеет следующие 3 компонента:
**Элемент данных** : хранит любые данные в узле **Левый указатель** : указывает на поддеревье в левой части узла **Правильный указатель** : указывает на поддерево справа от узла Как следует из названия, элемент данных хранит любые данные в узле. Левый и правый указатели указывают на двоичные деревья с левой и правой стороны узла соответственно.
Если дерево пустое, оно представлено нулевым указателем.
## Терминология, используемая в деревьях:
**Корень** : Верхний узел в дереве.
**Ребенок** : Узел, напрямую подключенный к другому узлу при удалении от корня.
**Родитель** : Обратное понятие ребенка.
**Братья и сестры** : Группа узлов с одним и тем же родителем.
**Потомок** : Узлы достижимы путем повторного прохождения от родителя к дочернему.
**Предки** : Узел, доступный путем повторного прохождения от дочернего к родительскому.
**Ветвь** (внутренний узел): Узел дерева с дочерними узлами.
**Лист** (обычно называемый внешним узлом): Узел без детей.
**Степень** : Количество поддеревьев узла.
**Край** : Связь между одним узлом и другим.
**Путь** : Последовательность узлов и ребер, соединяющих узел с потомком.
**Уровень** : Уровень узла определяется 1 + (количество соединений между узлом и корнем).
**Высота дерева** : Высота дерева - это высота его корневого узла.
**Глубина** : Глубина узла - это количество ребер от корневого узла дерева до узла.
**Лес** : Лес представляет собой набор из n ≥ 0 непересекающихся деревьев.
### Некоторые популярные типы деревьев:
* Двоичное дерево
* Двоичное дерево поиска
* Дерево AVL
* Красный Черный Дерево
* Splay Tree
* Дерево Хаффмана
### Общее использование
* Представление иерархических данных
* Хранение данных таким образом, чтобы он был легко доступен для поиска
* Представление отсортированных списков данных
* Алгоритмы маршрутизации
### Код узла дерева
\`\` \`c\_cpp узел структуры { int данные; // Элемент данных struct node \* left; // Указатель на левый узел struct node \* right; // Указатель на правый узел };
\`\` \`
#### Дополнительная информация:
* [Уроки урока CMU](http://www.cs.cmu.edu/~clo/www/CMU/DataStructures/Lessons/lesson4_1.htm)
* [Википедия](https://en.wikipedia.org/wiki/Tree_(data_structure))