Skip to content

Commit faccf74

Browse files
author
Anton Gorinenko
committed
Куча
1 parent 4d66557 commit faccf74

File tree

5 files changed

+98
-9
lines changed

5 files changed

+98
-9
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@
3535

3636
[Куча](tutorial/heap.md)
3737

38-
[Очередь с приоритетом](tutorial/heap.md) (в работе)
38+
[Очередь с приоритетом](tutorial/priority_queue.md) (в работе)
3939

40-
[Двухсторонняя очередь](tutorial/heap.md) (в работе)
40+
[Двухсторонняя очередь](tutorial/deque.md) (в работе)
4141

4242
### Алгоритмы
4343

tutorial/deque.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
## Двухсторонняя очередь

tutorial/heap.md

Lines changed: 94 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ class MinHeap:
7272
def __init__(self):
7373
self.heap_list = []
7474

75+
def is_empty(self):
76+
return not bool(self.heap_list)
77+
7578
def push(self, key: int):
7679
""" Добавление в кучу """
7780
self.heap_list.append(key)
@@ -84,16 +87,24 @@ class MinHeap:
8487

8588
def peek(self):
8689
""" Получение минимума """
87-
return self.heap_list[0]
90+
if len(self.heap_list) > 0:
91+
return self.heap_list[0]
92+
93+
return None
8894

8995
def pop(self):
9096
""" Извлечение с вершины кучи """
97+
if len(self.heap_list) == 1:
98+
return self.heap_list.pop()
99+
91100
result = self.peek()
92101
# Берем самый правый в последнем ряду элемент и переносим его на место удаляемого элемента
93102
self.heap_list[0] = self.heap_list.pop()
94103
cur_idx = 0
95-
max_idx = len(self.heap_list) - 1
104+
96105
while True:
106+
max_idx = len(self.heap_list) - 1
107+
97108
left_idx = _get_left_child_index(cur_idx)
98109
right_idx = _get_right_child_index(cur_idx)
99110

@@ -103,14 +114,90 @@ class MinHeap:
103114

104115
if left_idx <= max_idx and right_idx <= max_idx:
105116
# Если у просеиваемого элемента два сына
106-
min_idx = left_idx if self.heap_list[left_idx] < self.heap_list[right_idx] else right_idx
117+
max_child_idx = left_idx if self.heap_list[left_idx] < self.heap_list[right_idx] else right_idx
107118
elif left_idx <= max_idx:
108-
min_idx = left_idx
119+
max_child_idx = left_idx
120+
else:
121+
max_child_idx = right_idx
122+
123+
if self.heap_list[max_child_idx] < self.heap_list[cur_idx]:
124+
self.heap_list[cur_idx], self.heap_list[max_child_idx] = self.heap_list[max_child_idx], self.heap_list[
125+
cur_idx]
126+
cur_idx = max_child_idx
109127
else:
110-
min_idx = right_idx
128+
break
111129

112-
self.heap_list[cur_idx], self.heap_list[min_idx] = self.heap_list[min_idx], self.heap_list[cur_idx]
113-
cur_idx = min_idx
130+
return result
131+
132+
def _get_parent(self, idx: int) -> int:
133+
""" Получение родительского ключа """
134+
parent_idx = _get_parent_index(idx)
135+
return self.heap_list[parent_idx]
136+
137+
def __str__(self):
138+
return str(self.heap_list)
139+
140+
141+
class MaxHeap:
142+
""" Реализация кучи максимума на python с использованием массива """
143+
144+
def __init__(self):
145+
self.heap_list = []
146+
147+
def is_empty(self):
148+
return not bool(self.heap_list)
149+
150+
def push(self, key: int):
151+
""" Добавление в кучу """
152+
self.heap_list.append(key)
153+
cur_idx = len(self.heap_list) - 1
154+
while cur_idx > 0 and self.heap_list[cur_idx] > self._get_parent(cur_idx):
155+
parent_idx = _get_parent_index(cur_idx)
156+
# Меняем текущий элемент с родителем
157+
self.heap_list[cur_idx], self.heap_list[parent_idx] = self.heap_list[parent_idx], self.heap_list[cur_idx]
158+
cur_idx = parent_idx
159+
160+
def peek(self):
161+
""" Получение минимума """
162+
if len(self.heap_list) > 0:
163+
return self.heap_list[0]
164+
165+
return None
166+
167+
def pop(self):
168+
""" Извлечение с вершины кучи """
169+
if len(self.heap_list) == 1:
170+
return self.heap_list.pop()
171+
172+
result = self.peek()
173+
# Берем самый правый в последнем ряду элемент и переносим его на место удаляемого элемента
174+
self.heap_list[0] = self.heap_list.pop()
175+
cur_idx = 0
176+
177+
while True:
178+
max_idx = len(self.heap_list) - 1
179+
180+
left_idx = _get_left_child_index(cur_idx)
181+
right_idx = _get_right_child_index(cur_idx)
182+
183+
if left_idx > max_idx and right_idx > max_idx:
184+
# Если после перестановки у просеиваемого элемента нет сыновей, то завершаем алгоритм
185+
break
186+
187+
if left_idx <= max_idx and right_idx <= max_idx:
188+
# Если у просеиваемого элемента два сына
189+
max_child_idx = left_idx if self.heap_list[left_idx] > self.heap_list[right_idx] else right_idx
190+
elif left_idx <= max_idx:
191+
max_child_idx = left_idx
192+
else:
193+
max_child_idx = right_idx
194+
195+
if self.heap_list[max_child_idx] > self.heap_list[cur_idx]:
196+
self.heap_list[cur_idx], self.heap_list[max_child_idx] = self.heap_list[max_child_idx], self.heap_list[
197+
cur_idx]
198+
cur_idx = max_child_idx
199+
else:
200+
break
114201

115202
return result
116203

tutorial/img.png

-33.5 KB
Binary file not shown.

tutorial/priority_queue.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Очередь с приоритетом

0 commit comments

Comments
 (0)