479 lines
20 KiB
Markdown
479 lines
20 KiB
Markdown
# Review 5
|
|
|
|
* Hajin Ju, 2024062806
|
|
|
|
## Problem 1
|
|
|
|
Illustrate the operation of `HEAPSORT` on the array $A = \set{5, 13, 2, 25, 7, 17, 20, 8, 4}$
|
|
|
|
### Solution 1
|
|
|
|
* BUILD-MAX-HEAP
|
|
|
|
```python { cmd, output='html' hide }
|
|
from bs4 import BeautifulSoup
|
|
import math
|
|
|
|
# --- SVG 생성을 위한 설정값 ---
|
|
CONFIG = {
|
|
'canvas_padding': 10,
|
|
'node_radius': 12,
|
|
'font_size': 10,
|
|
'x_spacing': 30, # 형제 노드 간 최소 수평 간격
|
|
'y_spacing': 40, # 세대 간 수직 간격
|
|
'stroke_width': 1.5,
|
|
'colors': {
|
|
'node_border': '#aaa',
|
|
'node_bg': '#fff',
|
|
'node_text': '#333',
|
|
'line': '#ccc',
|
|
'active_border': '#c0392b',
|
|
'active_bg': '#f2d7d5',
|
|
}
|
|
}
|
|
|
|
def calculate_positions(arr):
|
|
"""2-Pass 알고리즘을 사용하여 노드 좌표를 계산합니다."""
|
|
positions = {}
|
|
if not arr:
|
|
return {}, 0, 0
|
|
|
|
initial_y = CONFIG['canvas_padding'] + CONFIG['node_radius']
|
|
|
|
# 1단계: In-order 순회로 겹치지 않는 초기 x 좌표 할당
|
|
x_next = 0
|
|
def assign_initial_x(i):
|
|
nonlocal x_next
|
|
if i >= len(arr) or arr[i] is None:
|
|
return
|
|
|
|
assign_initial_x(2 * i + 1) # 왼쪽 서브트리
|
|
|
|
y = int(math.log2(i + 1)) * CONFIG['y_spacing'] + initial_y
|
|
positions[i] = (x_next, y)
|
|
x_next += CONFIG['x_spacing']
|
|
|
|
assign_initial_x(2 * i + 2) # 오른쪽 서브트리
|
|
|
|
assign_initial_x(0)
|
|
|
|
# 2단계: Post-order 순회로 부모 노드를 자식들의 중앙으로 재조정
|
|
def center_parents(i):
|
|
if i >= len(arr) or arr[i] is None:
|
|
return
|
|
|
|
left_child, right_child = 2 * i + 1, 2 * i + 2
|
|
|
|
center_parents(left_child)
|
|
center_parents(right_child)
|
|
|
|
has_left = left_child < len(arr) and left_child in positions
|
|
has_right = right_child < len(arr) and right_child in positions
|
|
|
|
# 자식이 있는 경우에만 부모 위치 조정
|
|
if has_left and has_right:
|
|
# 자식이 둘 다 있으면 그 중앙으로 이동
|
|
left_x = positions[left_child][0]
|
|
right_x = positions[right_child][0]
|
|
positions[i] = ((left_x + right_x) / 2, positions[i][1])
|
|
elif has_left and not has_right:
|
|
# 왼쪽 자식만 있으면 그 위로 이동
|
|
positions[i] = (positions[left_child][0], positions[i][1])
|
|
elif not has_left and has_right:
|
|
# 오른쪽 자식만 있으면 그 위로 이동
|
|
positions[i] = (positions[right_child][0], positions[i][1])
|
|
|
|
center_parents(0)
|
|
|
|
# 맨 왼쪽 노드가 잘리지 않도록 전체 트리 이동
|
|
if not positions: return {}, 0, 0
|
|
min_x = min(p[0] for p in positions.values())
|
|
x_shift = 0
|
|
if min_x < CONFIG['canvas_padding'] + CONFIG['node_radius']:
|
|
x_shift = -min_x + CONFIG['canvas_padding'] + CONFIG['node_radius']
|
|
|
|
shifted_positions = {i: (x + x_shift, y) for i, (x, y) in positions.items()}
|
|
|
|
max_x = max(p[0] for p in shifted_positions.values())
|
|
max_y = max(p[1] for p in shifted_positions.values())
|
|
canvas_width = max_x + CONFIG['canvas_padding'] + CONFIG['node_radius']
|
|
canvas_height = max_y + CONFIG['canvas_padding'] + CONFIG['node_radius']
|
|
|
|
return shifted_positions, canvas_width, canvas_height
|
|
|
|
def create_single_tree_svg(soup, step_data):
|
|
# (이전과 동일, 변경 없음)
|
|
arr = step_data.get('heap', [])
|
|
highlighted = step_data.get('highlighted', set())
|
|
positions, width, height = calculate_positions(arr)
|
|
svg = soup.new_tag('svg', attrs={'width': width, 'height': height, 'xmlns': "http://www.w3.org/2000/svg"})
|
|
for i in range(len(arr)):
|
|
if i not in positions: continue
|
|
px, py = positions[i]
|
|
left_child, right_child = 2 * i + 1, 2 * i + 2
|
|
if left_child < len(arr) and left_child in positions:
|
|
cx, cy = positions[left_child]
|
|
svg.append(soup.new_tag('line', attrs={'x1': px, 'y1': py, 'x2': cx, 'y2': cy, 'stroke': CONFIG['colors']['line'], 'stroke-width': CONFIG['stroke_width']}))
|
|
if right_child < len(arr) and right_child in positions:
|
|
cx, cy = positions[right_child]
|
|
svg.append(soup.new_tag('line', attrs={'x1': px, 'y1': py, 'x2': cx, 'y2': cy, 'stroke': CONFIG['colors']['line'], 'stroke-width': CONFIG['stroke_width']}))
|
|
for i, val in enumerate(arr):
|
|
if i not in positions: continue
|
|
x, y = positions[i]
|
|
is_active = i in highlighted
|
|
svg.append(soup.new_tag('circle', attrs={'cx': x, 'cy': y, 'r': CONFIG['node_radius'], 'stroke': CONFIG['colors']['active_border'] if is_active else CONFIG['colors']['node_border'], 'stroke-width': CONFIG['stroke_width'], 'fill': CONFIG['colors']['active_bg'] if is_active else CONFIG['colors']['node_bg']}))
|
|
svg.append(soup.new_tag('text', attrs={'x': x, 'y': y, 'font-family': 'monospace', 'font-size': CONFIG['font_size'], 'text-anchor': 'middle', 'dominant-baseline': 'central', 'fill': CONFIG['colors']['node_text'], 'font-weight': 'bold' if is_active else 'normal'}))
|
|
svg.find_all('text')[-1].string = str(val)
|
|
return svg
|
|
|
|
def create_heap_visualization_div(steps_data):
|
|
# (이전과 동일, 변경 없음)
|
|
soup = BeautifulSoup("", "html.parser")
|
|
wrapper_div = soup.new_tag("div")
|
|
style = soup.new_tag("style")
|
|
style.string = """.heap-svg-flow { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; justify-content: flex-start; } .heap-svg-flow .arrow { font-size: 24px; color: #555; }"""
|
|
wrapper_div.append(style)
|
|
flow_container = soup.new_tag("div", attrs={"class": "heap-svg-flow"})
|
|
wrapper_div.append(flow_container)
|
|
for i, step in enumerate(steps_data):
|
|
svg_tree = create_single_tree_svg(soup, step)
|
|
flow_container.append(svg_tree)
|
|
if i < len(steps_data) - 1:
|
|
arrow = soup.new_tag("div", attrs={"class": "arrow"})
|
|
arrow.string = "→"
|
|
flow_container.append(arrow)
|
|
return wrapper_div.prettify()
|
|
|
|
# --- 🚀 메인 실행 부분 ---
|
|
if __name__ == "__main__":
|
|
MANUAL_STEPS = [
|
|
{"heap": [5, 13, 2, 25, 7, 17, 20, 8, 4], "highlighted": set()},
|
|
{"heap": [5, 13, 2, 25, 7, 17, 20, 8, 4], "highlighted": {8, 7, 3}},
|
|
{"heap": [5, 13, 20, 25, 7, 17, 2, 8, 4], "highlighted": {2, 5, 6}},
|
|
{"heap": [5, 25, 20, 13, 7, 17, 2, 8, 4], "highlighted": {1, 3, 4, 7, 8}},
|
|
{"heap": [25, 13, 20, 8, 7, 17, 2, 5, 4], "highlighted": {0, 1, 2, 3, 4, 5, 6, 7, 8}},
|
|
]
|
|
|
|
html_output = create_heap_visualization_div(MANUAL_STEPS)
|
|
print(html_output)
|
|
```
|
|
|
|
* EXTRACT-MAX
|
|
|
|
```python { cmd, output='html' hide }
|
|
from bs4 import BeautifulSoup
|
|
import math
|
|
|
|
# --- SVG 생성을 위한 설정값 ---
|
|
CONFIG = {
|
|
'canvas_padding': 10,
|
|
'node_radius': 12,
|
|
'font_size': 10,
|
|
'x_spacing': 30, # 형제 노드 간 최소 수평 간격
|
|
'y_spacing': 40, # 세대 간 수직 간격
|
|
'stroke_width': 1.5,
|
|
'colors': {
|
|
'node_border': '#aaa',
|
|
'node_bg': '#fff',
|
|
'node_text': '#333',
|
|
'line': '#ccc',
|
|
'active_border': '#c0392b',
|
|
'active_bg': '#f2d7d5',
|
|
}
|
|
}
|
|
|
|
def calculate_positions(arr):
|
|
"""2-Pass 알고리즘을 사용하여 노드 좌표를 계산합니다."""
|
|
positions = {}
|
|
if not arr:
|
|
return {}, 0, 0
|
|
|
|
initial_y = CONFIG['canvas_padding'] + CONFIG['node_radius']
|
|
|
|
# 1단계: In-order 순회로 겹치지 않는 초기 x 좌표 할당
|
|
x_next = 0
|
|
def assign_initial_x(i):
|
|
nonlocal x_next
|
|
if i >= len(arr) or arr[i] is None:
|
|
return
|
|
|
|
assign_initial_x(2 * i + 1) # 왼쪽 서브트리
|
|
|
|
y = int(math.log2(i + 1)) * CONFIG['y_spacing'] + initial_y
|
|
positions[i] = (x_next, y)
|
|
x_next += CONFIG['x_spacing']
|
|
|
|
assign_initial_x(2 * i + 2) # 오른쪽 서브트리
|
|
|
|
assign_initial_x(0)
|
|
|
|
# 2단계: Post-order 순회로 부모 노드를 자식들의 중앙으로 재조정
|
|
def center_parents(i):
|
|
if i >= len(arr) or arr[i] is None:
|
|
return
|
|
|
|
left_child, right_child = 2 * i + 1, 2 * i + 2
|
|
|
|
center_parents(left_child)
|
|
center_parents(right_child)
|
|
|
|
has_left = left_child < len(arr) and left_child in positions
|
|
has_right = right_child < len(arr) and right_child in positions
|
|
|
|
# 자식이 있는 경우에만 부모 위치 조정
|
|
if has_left and has_right:
|
|
# 자식이 둘 다 있으면 그 중앙으로 이동
|
|
left_x = positions[left_child][0]
|
|
right_x = positions[right_child][0]
|
|
positions[i] = ((left_x + right_x) / 2, positions[i][1])
|
|
elif has_left and not has_right:
|
|
# 왼쪽 자식만 있으면 그 위로 이동
|
|
positions[i] = (positions[left_child][0], positions[i][1])
|
|
elif not has_left and has_right:
|
|
# 오른쪽 자식만 있으면 그 위로 이동
|
|
positions[i] = (positions[right_child][0], positions[i][1])
|
|
|
|
center_parents(0)
|
|
|
|
# 맨 왼쪽 노드가 잘리지 않도록 전체 트리 이동
|
|
if not positions: return {}, 0, 0
|
|
min_x = min(p[0] for p in positions.values())
|
|
x_shift = 0
|
|
if min_x < CONFIG['canvas_padding'] + CONFIG['node_radius']:
|
|
x_shift = -min_x + CONFIG['canvas_padding'] + CONFIG['node_radius']
|
|
|
|
shifted_positions = {i: (x + x_shift, y) for i, (x, y) in positions.items()}
|
|
|
|
max_x = max(p[0] for p in shifted_positions.values())
|
|
max_y = max(p[1] for p in shifted_positions.values())
|
|
canvas_width = max_x + CONFIG['canvas_padding'] + CONFIG['node_radius']
|
|
canvas_height = max_y + CONFIG['canvas_padding'] + CONFIG['node_radius']
|
|
|
|
return shifted_positions, canvas_width, canvas_height
|
|
|
|
def create_single_tree_svg(soup, step_data):
|
|
# (이전과 동일, 변경 없음)
|
|
arr = step_data.get('heap', [])
|
|
highlighted = step_data.get('highlighted', set())
|
|
positions, width, height = calculate_positions(arr)
|
|
svg = soup.new_tag('svg', attrs={'width': width, 'height': height, 'xmlns': "http://www.w3.org/2000/svg"})
|
|
for i in range(len(arr)):
|
|
if i not in positions: continue
|
|
px, py = positions[i]
|
|
left_child, right_child = 2 * i + 1, 2 * i + 2
|
|
if left_child < len(arr) and left_child in positions:
|
|
cx, cy = positions[left_child]
|
|
svg.append(soup.new_tag('line', attrs={'x1': px, 'y1': py, 'x2': cx, 'y2': cy, 'stroke': CONFIG['colors']['line'], 'stroke-width': CONFIG['stroke_width']}))
|
|
if right_child < len(arr) and right_child in positions:
|
|
cx, cy = positions[right_child]
|
|
svg.append(soup.new_tag('line', attrs={'x1': px, 'y1': py, 'x2': cx, 'y2': cy, 'stroke': CONFIG['colors']['line'], 'stroke-width': CONFIG['stroke_width']}))
|
|
for i, val in enumerate(arr):
|
|
if i not in positions: continue
|
|
x, y = positions[i]
|
|
is_active = i in highlighted
|
|
svg.append(soup.new_tag('circle', attrs={'cx': x, 'cy': y, 'r': CONFIG['node_radius'], 'stroke': CONFIG['colors']['active_border'] if is_active else CONFIG['colors']['node_border'], 'stroke-width': CONFIG['stroke_width'], 'fill': CONFIG['colors']['active_bg'] if is_active else CONFIG['colors']['node_bg']}))
|
|
svg.append(soup.new_tag('text', attrs={'x': x, 'y': y, 'font-family': 'monospace', 'font-size': CONFIG['font_size'], 'text-anchor': 'middle', 'dominant-baseline': 'central', 'fill': CONFIG['colors']['node_text'], 'font-weight': 'bold' if is_active else 'normal'}))
|
|
svg.find_all('text')[-1].string = str(val)
|
|
return svg
|
|
|
|
def create_heap_visualization_div(steps_data):
|
|
# (이전과 동일, 변경 없음)
|
|
soup = BeautifulSoup("", "html.parser")
|
|
wrapper_div = soup.new_tag("div")
|
|
style = soup.new_tag("style")
|
|
style.string = """.heap-svg-flow { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; justify-content: flex-start; } .heap-svg-flow .arrow { font-size: 24px; color: #555; }"""
|
|
wrapper_div.append(style)
|
|
flow_container = soup.new_tag("div", attrs={"class": "heap-svg-flow"})
|
|
wrapper_div.append(flow_container)
|
|
for i, step in enumerate(steps_data):
|
|
svg_tree = create_single_tree_svg(soup, step)
|
|
flow_container.append(svg_tree)
|
|
if i < len(steps_data) - 1:
|
|
arrow = soup.new_tag("div", attrs={"class": "arrow"})
|
|
arrow.string = "→"
|
|
flow_container.append(arrow)
|
|
return wrapper_div.prettify()
|
|
|
|
# --- 🚀 메인 실행 부분 ---
|
|
if __name__ == "__main__":
|
|
MANUAL_STEPS = [
|
|
{"heap": [25, 13, 20, 8, 7, 17, 2, 5, 4], "highlighted": set()},
|
|
{"heap": [20, 13, 17, 8, 7, 4, 2, 5], "highlighted": set()},
|
|
{"heap": [17, 13, 5, 8, 7, 4, 2], "highlighted": set()},
|
|
{"heap": [13, 8, 5, 2, 7, 4], "highlighted": set()},
|
|
{"heap": [8, 7, 5, 2, 4], "highlighted": set()},
|
|
{"heap": [7, 4, 5, 2], "highlighted": set()},
|
|
]
|
|
|
|
html_output = create_heap_visualization_div(MANUAL_STEPS)
|
|
print(html_output)
|
|
```
|
|
|
|
```
|
|
out 25 -> out 20 -> out 17 -> out 13 -> out 8
|
|
```
|
|
|
|
* MAX-HEAP-INSERT(A, 15)
|
|
|
|
```python { cmd, output='html' hide }
|
|
from bs4 import BeautifulSoup
|
|
import math
|
|
|
|
# --- SVG 생성을 위한 설정값 ---
|
|
CONFIG = {
|
|
'canvas_padding': 10,
|
|
'node_radius': 12,
|
|
'font_size': 10,
|
|
'x_spacing': 30, # 형제 노드 간 최소 수평 간격
|
|
'y_spacing': 40, # 세대 간 수직 간격
|
|
'stroke_width': 1.5,
|
|
'colors': {
|
|
'node_border': '#aaa',
|
|
'node_bg': '#fff',
|
|
'node_text': '#333',
|
|
'line': '#ccc',
|
|
'active_border': '#c0392b',
|
|
'active_bg': '#f2d7d5',
|
|
}
|
|
}
|
|
|
|
def calculate_positions(arr):
|
|
"""2-Pass 알고리즘을 사용하여 노드 좌표를 계산합니다."""
|
|
positions = {}
|
|
if not arr:
|
|
return {}, 0, 0
|
|
|
|
initial_y = CONFIG['canvas_padding'] + CONFIG['node_radius']
|
|
|
|
# 1단계: In-order 순회로 겹치지 않는 초기 x 좌표 할당
|
|
x_next = 0
|
|
def assign_initial_x(i):
|
|
nonlocal x_next
|
|
if i >= len(arr) or arr[i] is None:
|
|
return
|
|
|
|
assign_initial_x(2 * i + 1) # 왼쪽 서브트리
|
|
|
|
y = int(math.log2(i + 1)) * CONFIG['y_spacing'] + initial_y
|
|
positions[i] = (x_next, y)
|
|
x_next += CONFIG['x_spacing']
|
|
|
|
assign_initial_x(2 * i + 2) # 오른쪽 서브트리
|
|
|
|
assign_initial_x(0)
|
|
|
|
# 2단계: Post-order 순회로 부모 노드를 자식들의 중앙으로 재조정
|
|
def center_parents(i):
|
|
if i >= len(arr) or arr[i] is None:
|
|
return
|
|
|
|
left_child, right_child = 2 * i + 1, 2 * i + 2
|
|
|
|
center_parents(left_child)
|
|
center_parents(right_child)
|
|
|
|
has_left = left_child < len(arr) and left_child in positions
|
|
has_right = right_child < len(arr) and right_child in positions
|
|
|
|
# 자식이 있는 경우에만 부모 위치 조정
|
|
if has_left and has_right:
|
|
# 자식이 둘 다 있으면 그 중앙으로 이동
|
|
left_x = positions[left_child][0]
|
|
right_x = positions[right_child][0]
|
|
positions[i] = ((left_x + right_x) / 2, positions[i][1])
|
|
elif has_left and not has_right:
|
|
# 왼쪽 자식만 있으면 그 위로 이동
|
|
positions[i] = (positions[left_child][0], positions[i][1])
|
|
elif not has_left and has_right:
|
|
# 오른쪽 자식만 있으면 그 위로 이동
|
|
positions[i] = (positions[right_child][0], positions[i][1])
|
|
|
|
center_parents(0)
|
|
|
|
# 맨 왼쪽 노드가 잘리지 않도록 전체 트리 이동
|
|
if not positions: return {}, 0, 0
|
|
min_x = min(p[0] for p in positions.values())
|
|
x_shift = 0
|
|
if min_x < CONFIG['canvas_padding'] + CONFIG['node_radius']:
|
|
x_shift = -min_x + CONFIG['canvas_padding'] + CONFIG['node_radius']
|
|
|
|
shifted_positions = {i: (x + x_shift, y) for i, (x, y) in positions.items()}
|
|
|
|
max_x = max(p[0] for p in shifted_positions.values())
|
|
max_y = max(p[1] for p in shifted_positions.values())
|
|
canvas_width = max_x + CONFIG['canvas_padding'] + CONFIG['node_radius']
|
|
canvas_height = max_y + CONFIG['canvas_padding'] + CONFIG['node_radius']
|
|
|
|
return shifted_positions, canvas_width, canvas_height
|
|
|
|
def create_single_tree_svg(soup, step_data):
|
|
# (이전과 동일, 변경 없음)
|
|
arr = step_data.get('heap', [])
|
|
highlighted = step_data.get('highlighted', set())
|
|
positions, width, height = calculate_positions(arr)
|
|
svg = soup.new_tag('svg', attrs={'width': width, 'height': height, 'xmlns': "http://www.w3.org/2000/svg"})
|
|
for i in range(len(arr)):
|
|
if i not in positions: continue
|
|
px, py = positions[i]
|
|
left_child, right_child = 2 * i + 1, 2 * i + 2
|
|
if left_child < len(arr) and left_child in positions:
|
|
cx, cy = positions[left_child]
|
|
svg.append(soup.new_tag('line', attrs={'x1': px, 'y1': py, 'x2': cx, 'y2': cy, 'stroke': CONFIG['colors']['line'], 'stroke-width': CONFIG['stroke_width']}))
|
|
if right_child < len(arr) and right_child in positions:
|
|
cx, cy = positions[right_child]
|
|
svg.append(soup.new_tag('line', attrs={'x1': px, 'y1': py, 'x2': cx, 'y2': cy, 'stroke': CONFIG['colors']['line'], 'stroke-width': CONFIG['stroke_width']}))
|
|
for i, val in enumerate(arr):
|
|
if i not in positions: continue
|
|
x, y = positions[i]
|
|
is_active = i in highlighted
|
|
svg.append(soup.new_tag('circle', attrs={'cx': x, 'cy': y, 'r': CONFIG['node_radius'], 'stroke': CONFIG['colors']['active_border'] if is_active else CONFIG['colors']['node_border'], 'stroke-width': CONFIG['stroke_width'], 'fill': CONFIG['colors']['active_bg'] if is_active else CONFIG['colors']['node_bg']}))
|
|
svg.append(soup.new_tag('text', attrs={'x': x, 'y': y, 'font-family': 'monospace', 'font-size': CONFIG['font_size'], 'text-anchor': 'middle', 'dominant-baseline': 'central', 'fill': CONFIG['colors']['node_text'], 'font-weight': 'bold' if is_active else 'normal'}))
|
|
svg.find_all('text')[-1].string = str(val)
|
|
return svg
|
|
|
|
def create_heap_visualization_div(steps_data):
|
|
# (이전과 동일, 변경 없음)
|
|
soup = BeautifulSoup("", "html.parser")
|
|
wrapper_div = soup.new_tag("div")
|
|
style = soup.new_tag("style")
|
|
style.string = """.heap-svg-flow { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; justify-content: flex-start; } .heap-svg-flow .arrow { font-size: 24px; color: #555; }"""
|
|
wrapper_div.append(style)
|
|
flow_container = soup.new_tag("div", attrs={"class": "heap-svg-flow"})
|
|
wrapper_div.append(flow_container)
|
|
for i, step in enumerate(steps_data):
|
|
svg_tree = create_single_tree_svg(soup, step)
|
|
flow_container.append(svg_tree)
|
|
if i < len(steps_data) - 1:
|
|
arrow = soup.new_tag("div", attrs={"class": "arrow"})
|
|
arrow.string = "→"
|
|
flow_container.append(arrow)
|
|
return wrapper_div.prettify()
|
|
|
|
# --- 🚀 메인 실행 부분 ---
|
|
if __name__ == "__main__":
|
|
MANUAL_STEPS = [
|
|
{"heap": [16, 14, 10, 8, 7, 9, 3, 2, 4, 1], "highlighted": set()},
|
|
{"heap": [16, 14, 10, 8, 7, 9, 3, 2, 4, 1, 15], "highlighted": {10}},
|
|
{"heap": [16, 15, 10, 8, 14, 9, 3, 2, 4, 1, 7], "highlighted": set()},
|
|
]
|
|
|
|
html_output = create_heap_visualization_div(MANUAL_STEPS)
|
|
print(html_output)
|
|
```
|
|
|
|
## Problem 2
|
|
|
|
Fill in the blanks in the following pseudocode for Heapsort.
|
|
|
|
### Solution 2
|
|
|
|
```{ .line-numbers }
|
|
HEAPSORT(A)
|
|
BUILD-MAX-HEAP
|
|
for i = A.length downto 2
|
|
exchange A[1] with A[i]
|
|
A.heap-size = A.heap-size - 1
|
|
MAX-HEAPIFY(A, 1)
|
|
```
|
|
|