[TIL]アルゴリズム&データ構造:ツリーとバイナリインデックスツリー
17465 ワード
3.ツリー構造
意図したように階層を表すデータ構造.
3-1. バイナリ検索ツリー
3-2. 木の回り
ツリーリソース構造に含まれるノードに特定の方法でアクセスする方法.ツリー内の情報を直感的に見ることができるため、よく使われます.
・뉭묭・電位めぐり:根장左側장右側장장・장8・
・7・中尉巡り:左式❵根❵右式・8・
・뉭묭・後列巡り:左側장장右側장장장장・장8・
class Node:
def __init__(self, data, left_node, right_node):
self.data = data
self.left_node = left_node
self.right_node = right_node
# 전위 순회
def pre_order(node):
print(node.data, end=' ')
if node.left_node != None:
in_order(tree[node.left_node])
print(node.data, end=' ')
if node.right_node != None:
in_order(tree[node.right_node])
# 중위 순회
def in_dorder(node):
if node.left_node != None:
in_order(tree[node.left_node])
print(node.data, end=' ')
if node.right_node != Nonde:
in_order(tree[node.right_node])
# 후위 순회
def post_order(node):
if node.left_node != None:
post_order(tree[node.left_node])
if node.right_node != None:
post_order(tree[node.right_node])
print(node.data, end=' ')
n = int(input())
tree = []
for i in range(n):
data, left_node, right_node = input().split()
if left_node == "None":
left_node = None
if right_node == "None":
right_node = None
tree[data] = Node(data, left_node, right_node)
pre_order(tree['A'])
print()
in_order(tree['A'])
print()
post_order(tree['A'])
4.バイナリインデックスツリー
a.k.a.BIT、フィンウィックの木.バイナリインデックス構造を用いて区間連結問題を効果的に解決するデータ構造
👉 区間連結アルゴリズム問題:https://www.acmicpc.net/problem/2042
整数のバイナリタグの例
整数バイナリ数表記700000000000000000000000011-711111111111111001
0以外の最後のビットを検索します.
n = 8
for i in range(n+1):
print(i, "의 마지막 비트:", (i & -i))
バイナリインデックスツリー実装動作原理
≪作成|Create|ldap≫:0以外の最後の値=保存した値の数
更新
特定の値を変更した場合:区間の値を0ではなく最下位に変更します.
例)3回値の変更:1~4回値の変更、1~8回値の変更、1~16回値の変更
累計和を求める
1からNまでの累計和:0ではなく最後のビットを減算し、区間値の和を計算します.
例)累計11回和:11回値+9~10回値+1~8回値を求める
import sys
input = sys.stdin.readline
# 데이터의 개수(n), 변경 횟수(m), 구간 합 계산 횟수(k)
n, m, k = map(int, input().split())
# 전체 데이터의 개수는 최대 1,000,000개
arr = [0] * (n + 1)
tree = [0] * (n + 1)
# i번째 수까지의 누적 합을 계산하는 함수
def prefix_sum(i):
result = 0
while i > 0:
result += tree[i]
# 0이 아닌 마지막 비트만큼 빼가면서 이동
i -= (i & -i)
return result
# i번째 수를 dif만큼 더하는 함수
def update(i, dif):
while i <= n:
tree[i] += dif
i += (i & -i)
# start부터 end까지의 구간 합을 계산하는 함수
def interval_sum(start, end):
return prefix_sum(end) - prefix_sum(start - 1)
for i in range(1, n + 1):
x = int(input())
arr[i] = x
update(i, x)
for i in range(m + k):
a, b, c = map(int, input().split())
# 업데이트 연산인 경우
if a == 1:
update(b, c - arr[b]) # 바뀐 크기(dif)만큼 적용
else:
print(interval_sum(b, c))
Reference
この問題について([TIL]アルゴリズム&データ構造:ツリーとバイナリインデックスツリー), 我々は、より多くの情報をここで見つけました https://velog.io/@minami/알고리즘자료구조-트리와-바이너리-인덱스-트리テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol