24일차 알고리즘 기초2

차지예·2025년 6월 18일

생성AI

목록 보기
20/56
post-thumbnail

트리(tree)

이진트리 용어

용어설명
노드 (Node)트리의 각 요소A, B, C 등
간선 (Edge)노드끼리 연결하는 선A–B, A–C
깊이 (Depth)루트에서 해당 노드까지의 간선 수A의 깊이: 0B의 깊이: 1
레벨 (Level)깊이 + 1A: 1레벨, B: 2레벨
노드의 차수 (Degree)자식 노드의 수A의 차수: 2 (B, C)
트리의 차수모든 노드의 차수 중 최대값A(2), B(2), G(2) → 2
높이 (Height)루트에서 가장 깊은 노드까지의 정점 수루트 A → G → I → 총 4개 노드⇒ 트리 높이: 4
루트 노드 (Root Node)트리의 시작점A
단말 노드 (Leaf Node)자식이 없는 노드E, F, C, H, I
내부 노드 (Internal Node)자식이 있는 노드 (루트 포함)A, B, D, G
부모 노드 (Parent Node)자식을 가진 상위 노드B는 E와 F의 부모
자식 노드 (Child Node)부모에 연결된 하위 노드E는 B의 자식
형제 노드 (Sibling Node)같은 부모를 가진 노드들E와 F는 형제
조상 노드 (Ancestor)해당 노드부터 루트까지의 상위 노드I의 조상: G, D, A
후손 노드 (Descendant)해당 노드의 하위 모든 노드D의 후손: G, H, I

code

class Node:  
	def __init__(self, item):
    	self.item = item
        self.left = None
        self.right = None
        
class BinaryTree():
	def __init__(self): 
    	self.root = None        

전위 순회 (Preorder)

  • 자기 자신을 먼저 출력하고 자식 노드를 호출한다.
  • 자기 자신 출력 -> 왼쪽 서브 트리 호출 -> 오른쪽 서브 트리 호출
def preorder(self, n):
	if n!= None:
    	print(n.item, '', end='') # 노드 방문
        if n.left:
        	self.preodrer(n.left) # 왼쪽 서브 트리 순회
        if n.right:
        	self.preodrer(n.right) # 오른쪽 서브 트리 순회

후위 순회 (Postorder)

  • 자기 자신 출력을 가장 나중에 한다.
  • 왼쪽 서브 트리 호출 -> 오른쪽 서브 트리 호출 -> 자기 자신 출력
# 후위 순회
def postorder(self, n):
	if n!= None:
    	if n.left:
        	self.postorder(n.left)
        if n.right:
        	self.postorder(n.right)
        print(n.item, '', end='') # 노드 방문

중위 순회 (Inorder)

  • 자기 자신 출력이 중간에 있다
  • 왼쪽 서브 트리 호출 -> 자기 자신 출력 -> 오른쪽 서브 트리 호출
# 중위 순회
def inorder(self, n):
	if n!= None:
    	if n.left:
        	self.inorder(n.left)
        print(n.item, '', end='') # 노드 방문
    if n.right:
    	self.inorder(n.right)

레벨 순회 (Levelorder)

  • 깊이(레벨) 단위로 출력
# 레벨 순회
def levelorder(self, n):
	q = []
    q.append(n)
    while q:
    	t = q.pop(0)
        print(t.item, '', end='')
        if t.left != None:
        	q.append(t.left)
        if t.right != None:
        	q.append(t.right)

hash 테이블

  • 정의: 키를 해시 함수로 변환하여 데이터를 저장하는 구조
  • 특징:
    • 평균 시간 복잡도: 삽입, 삭제, 탐색 모두 O(1)
    • 해시 충돌이 발생할 수 있어 처리 방식 필요 (체이닝, 오픈 어드레싱 등)
  • 활용 예시: 딕셔너리, 캐시, 데이터베이스 인덱싱
hash_table = {}
hash_table["apple"] = 10
print(hash_table["apple"])  # 출력: 10

충돌(Collision)

서로 다른 키가 같은 해시값을 가질 경우를 충돌(Collision)이라고 합니다.

해결 방법:

  1. 체이닝(Chaining)
  • 같은 인덱스에 여러 데이터를 리스트(Linked List) 형태로 저장
table[3] = [(103, 'apple'), (203, 'banana')]
  1. 개방 주소법(Open Addressing)
  • 충돌이 발생하면 다음 인덱스를 선형/제곱 방식 등으로 탐색
  • 종류: 선형 탐사(Linear Probing), 제곱 탐사(Quadratic Probing), 이중 해싱(Double Hashing)

해시 테이블의 장점

장점설명
빠른 접근 속도평균적으로 O(1)의 시간 복잡도
효율적인 검색키만 있으면 빠르게 데이터 검색 가능
유연한 키 사용문자열, 정수 등 다양한 타입의 키 사용 가능

해시 테이블의 단점

단점설명
충돌 처리 필요해시 충돌이 성능 저하 원인이 될 수 있음
메모리 낭비 가능성해시 테이블 크기를 넉넉하게 설정해야 함
순차 접근 불가인덱스 순으로 정렬된 상태를 보장하지 않음

0개의 댓글