이진 트리이진 트리
🗒

이진 트리

다루고 있는 개념
No
난이도
Type
자료
file

이진트리

이진트리란 자식 노드가 최대 두 개인 노드들로 구성된 트리이다.
컴퓨터 과학에서 이진 탐색 트리(BST: binary search tree)는 다음과 같은 속성이 있는 이진 트리 자료 구조이다.
  • 각 노드에 값이 있다.
  • 값들은 전순서가 있다.
  • 노드의 왼쪽 서브트리에는 그 노드의 값보다 작은 값들을 지닌 노드들로 이루어져 있다.
  • 노드의 오른쪽 서브트리에는 그 노드의 값과 같거나 큰 값들을 지닌 노드들로 이루어져 있다.
  • 좌우 하위 트리는 각각이 다시 이진 탐색 트리여야 한다.
notion imagenotion image

포화 이진트리

모든 노드가 두 개의 자식 노드를 가지며 모든 잎 노드가 동일한 레벨을 갖는다.
notion imagenotion image

완전 이진트리

마지막 레벨을 제외하고 모든 레벨이 완전히 채워져 있으며, 마지막 레벨에서는 왼쪽부터 노드가
순서대로 채워져 있다.
notion imagenotion image

이진트리의 순회

전위 순회

루트 노드부터 잎 노드까지 아래 방향으로 순회
  1. 자신 노드
  1. 왼쪽 노드
  1. 오른쪽 노드
    1. notion imagenotion image

중위 순회

왼쪽 하위 노드부터 오른쪽 하뤼 노드 방향으로 방문
  1. 왼쪽 노드
  1. 자신 노드
  1. 오른쪽 노드
    1. notion imagenotion image

후진 순회

잎 노드를 모두 탐색하고 루트 노드를 방문
  1. 왼쪽 노드
  1. 오른쪽 노드
  1. 자신 노드
    1. notion imagenotion image

이진 탐색 트리

탐색을 위한 이진트리
왼쪽 자식 노드는 자신보다 작고, 오른쪽 자식 노드는 자신보다 크다는 특징이 있다.

깊이 우선 탐색

깊이 우선 탐색 (depth-first search: DFS)은 맹목적 탐색방법의 하나로 탐색트리의 최근에 첨가된 노드를 선택하고, 이 노드에 적용 가능한 동작자 중 하나를 적용하여 트리에 다음 수준(level)의 한 개의 자식노드를 첨가하며, 첨가된 자식 노드가 목표노드일 때까지 앞의 자식 노드의 첨가 과정을 반복해 가는 방식이다. (출처 :https://ko.wikipedia.org/wiki/깊이_우선_탐색)
깊이 우선 탐색은 스택(stack)을 사용해서 탐색한다.
notion imagenotion image
노란색 노드는 아직 방문하지 않은 노드, 초록색 노드는 방문한 노드이며, 스택에 담겨서 Current로, Current에서 방문경로로 이동하는 순간 그 노드와 연결되어 있던 노드들이 스택(Stack)으로 들어가게 된다.(문제 5번 설명 참고)
notion imagenotion image
 
 

너비 우선 탐색

너비 우선 탐색(Breadth-first search, BFS)은 맹목적 탐색방법의 하나로 시작 정점을 방문한 후 시작 정점에 인접한 모든 정점들을 우선 방문하는 방법이다. 더 이상 방문하지 않은 정점이 없을 때까지 방문하지 않은 모든 정점들에 대해서도 너비 우선 검색을 적용한다. OPEN List 는 큐를 사용해야만 레벨 순서대로 접근이 가능하다. (출처 :https://ko.wikipedia.org/wiki/너비_우선_탐색)
notion imagenotion image
노란색 노드는 아직 방문하지 않은 노드, 초록색 노드는 방문한 노드이며, 스택에 담겨서 Current로, Current에서 방문경로로 이동하는 순간 그 노드와 연결되어 있던 노드들이 큐(Queue)로 들어가게 된다.(문제 5번 설명 참고)
notion imagenotion image
 
 

이진 탐색 트리에서의 검색

  • 이진탐색트리에서 키 x를 가진 노드를 검색하고자 할때, 트리에 해당 노드가 존재하면 해당 노드를 리턴하고, 존재하지 않으면 NULL을 리턴한다.
  • 검색하고자 하는 값을 루트노드와 먼저 비교하고, 일치할 경우 루트노드를 리턴한다.
    • 불일치하고 검색하고자 하는 값이 루트노드의 값보다 작을 경우 왼쪽 서브트리에서 재귀적으로 검색한다.
    • 불일치하고 검색하고자 하는 값이 루트노드의 값과 같거나 큰 경우 오른쪽 서브트리에서 재귀적으로 검색한다.
    •  

삽입

notion imagenotion image
  • 삽입을 하기 전, 검색을 수행한다.
  • 트리를 검색한 후 키와 일치하는 노드가 없으면 마지막 노드에서 키와 노드의 크기를 비교하여서 왼쪽이나 오른쪽에 새로운 노드를 삽입한다.
  • Python 코드
def 삽입(값, 노드) : if 값 < 노드.값 : if 노드.왼쪽자식 is None : 노드.왼쪽자식 = TreeNode(값) else : 삽입(값, 노드.왼쪽자식) else 값 > 노드.값 : if 노드.오른쪽자식 is None : 노드.오른쪽자식 = TreeNode(값) else : 삽입(값, 노드.오른쪽자식)
 
  • Javascript 코드
function 삽입(data){ //노드 생성 const node = new Node(data, null, null); //루트노드가 존재하지 않을 경우 if(this.root == null){ this.root = node; } else { let current = this.root; let parent; while(true){ parent = current; if(data < current.data){ current = current.left; if(current == null){ parent.left = node; break; } } else { current = current.right; if(current == null){ parent.right = node; break; } } } } }

삭제

삭제하려는 노드의 자식 수에 따라
  • 자식노드가 없는 노드(리프 노드) 삭제 : 해당 노드를 단순히 삭제한다.
  • 자식노드가 1개인 노드 삭제 : 해당 노드를 삭제하고 그 위치에 해당 노드의 자식노드를 대입한다.
  • 자식노드가 2개인 노드 삭제 : 삭제하고자 하는 노드의 값을 해당 노드의 왼쪽 서브트리에서 가장 큰값으로 대체하거나, 오른쪽 서브트리에서 가장 작은 값으로 대체한 뒤, 해당 노드(왼쪽서브트리에서 가장 큰 값을 가지는 노드 또는 오른쪽 서브트리에서 가장 작은 값을 가지는 노드)를 삭제한다.
 
  • Python 코드
def 삭제(삭제값, 노드) : if 노드 is None : return None elif 삭제값 < 노드.값 : 노드.왼쪽자식 = 삭제(삭제값, 노드.왼쪽자식) return 노드 elif 삭제값 > 노드.값 : 노드.오른쪽자식 = 삭제(삭제값, 노드.오른쪽자식) return 노드 elif 삭제값 == 노드.값 : if 노드.왼쪽자식 is None : return 노드.오른쪽자식 elif 노드.오른쪽자식 if None : return 노드.왼쪽자식 else : 노드.오른쪽자식 = lift(노드.오른쪽자식, 노드) return 노드 def lift(노드, 삭제노드) : if 노드.왼쪽자식 : 노드.왼쪽자식 = lift(노드.왼쪽자식, 삭제노드) return 노드 else : 삭제노드.값 = 노드.값 return 노드.오른쪽자식
 
  • Javascript 코드
function del(node, data){ if(node == null){ return null; } if(data == node.data){ if(node.left == null && node.right == null){ return null; } if(node.left == null){ return node.right; } if(node.right == null){ return node.left; } //자식노드가 2개일 때 let tmp = this.delNode(node.right); //오른쪽 노드에서 가장 작은 값 가져오기 node.data = tmp.data; node.right = this.del(node.right, tempNode.data); return node; } else if(data < node.data){ node.left = this.del(node.left, data); return node; } else{ node.right = this.del(node.right, data); return node; } } function delNode(node){ let temp2 = node; while(tmp2.left !== null){ tmp2 = tmp2.left; } return tmp2; }

그 외

레드블랙트리

값이 루트 노드보다 작거나 큰 값만 들어올 경우 → 불균형한 이진탐색트리가 된다. 그러면 검색 효율이 저하된다.
notion imagenotion image
이를 보완해 주는 것이 레드블랙트리 이다.
notion imagenotion image
  1. 트리의 모든 노드는 검정색과 빨간색이다
  1. 루트 노드는 항상 검정색이다
  1. 모든 잎 노드는 검정색 이다
  1. 빨간색의 노드 자식들은 모두 검정색이지만, 검정색 노드 자식들은 검정색, 빨간색 모두 사용된다.
  1. 루트 노드에서 모든 잎 노드 사이에 있는 검정색 노드의 수는 모두 동일하다.