이번 주 부트캠프에서는 소프트웨어 개발의 근간이 되는 자료구조(Data Structure)와 알고리즘(Algorithm)에 대해 학습함
자료구조는 데이터를 어떻게 저장하고 구성할 것인지에 대한 방법
목적은 데이터를 효율적으로 삽입, 삭제, 탐색, 정렬할 수 있도록 하는 것

# 배열 예시
arr = [10, 20, 30]
arr.append(40)
print(arr[2]) # 출력: 30
# 연결 리스트 예시 (클래스로 직접 구현)
class Node:
def __init__(self, data):
self.data = data
self.next = None
node1 = Node(10)
node2 = Node(20)
node1.next = node2
print(node1.next.data) # 출력: 20
# 해시 테이블: 딕셔너리 사용
user_info = {
'superjinjung': 'jinjung1234@gmail.com',
'ai_learner': 'ai4life@naver.com'
}
print(user_info['superjinjung']) # O(1)
# 트리 구조: 이진 탐색 트리 구현
class Node:
def __init__(self, key):
self.key = key
self.left = None
self.right = None
def insert(root, key):
if not root:
return Node(key)
if key < root.key:
root.left = insert(root.left, key)
else:
root.right = insert(root.right, key)
return root
root = Node(50)
insert(root, 30)
insert(root, 70)
# 이진 탐색은 O(log n) 시간복잡도
알고리즘은 특정 문제를 해결하기 위한 일련의 절차나 규칙
같은 문제라도 어떤 알고리즘을 사용하느냐에 따라 성능 차이가 극명하게 나타나게 됨

def binary_search(arr, target):
left, right = 0, len(arr)-1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
arr = [10, 20, 30, 40, 50, 60]
print(binary_search(arr, 40)) # 출력: 3
# 비효율적인 재귀 방식 (O(2^n))
def fib_recursive(n):
if n <= 1:
return n
return fib_recursive(n-1) + fib_recursive(n-2)
# 효율적인 동적 계획법 (O(n))
def fib_dp(n):
dp = [0, 1]
for i in range(2, n+1):
dp.append(dp[i-1] + dp[i-2])
return dp[n]
print(fib_dp(10)) # 출력: 55
