[DB] B-Tree

2024. 9. 21. 00:36·Data Base

B Tree

 

 - 일반화된 Balanced Search Tree

 - 모든 리프들은 같은 depth를 갖는다 (비트리의 height)

 - 루트를 제외한 모든 노드는 최소한 t-1개의 키를 갖는다 (t >= 2)

 - 루트를 제외한 모든 인터널 노드는 최소한 t개의 자손을 갖는다

 - 모든 노드는 최대 2t-1개의 키를 갖는다

 - 따라서 모든 인터널 노드는 최대 2t개의 자손을 갖는다(리프 노드는 자손 없다)

 - 리프 노드를 제외하고, 모든 노드는 n개의 키를 가지면 자손의 개수는 n+1개이어야 한다

 

x.n : 노드 x에 저장되어 있는 키의 수

x.leaf : 불리언 값으로 x가 리프노드면 TRUE, x가 인터널 노드면 FALSE 값이 저장된다

x.key[1], x.key[2] ... x.key[x.n] : 오름차순으로 정렬되어 저장된다

x.c[1], x.c[2] ... x.c[x.n+1] : 자식노드를 가리키는 포인터들

 

 

높이의 최대값 (Upper Bound of Height) : Worst-case Height

 

 

 

 

위의 식을 통해서 O(h) = O(log t N) 임을 알 수 있다 

 

 

검색(Search)

 

- 입력값

x : 루트 노드를 가리키는 포인터 (서브 트리의 루트인 경우도)

k : 해당 서브 트리에서 찾고자 하는 키값

 

- 출력값

k 값이 트리에 존재하는 경우 : (y, i)  노드 포인터 y와 index i (y의 키들 중 i번째에 key가 존재)

k 값이 트리에 존재하지 않는 경우 : NIL

 

BTreeSearch(x, k):
    i = 1
    while i <= x.n and k > key : 
    	i += 1
    if i <= x.n and k == key : 
    	return (x, i)
    else if x.leaf : 
    	return NIL
    else : 
    	return BTreeSearch(x.ci, k)

 

 

 

 

 

시간복잡도 

 

각 노드에서 키를 선형탐색으로 찾는 경우 

O(h) * O(t) = O(t * log t N)

 

각 노드에서 키를 이진탐색으로 찾는 경우 

O(log t N) * O(log 2 t) = O(log 2 N)

 

 

 

삽입(Insert)

 

 - 이미 존재하는 리프 노드에 새로운 키를 삽입한다

 - 리프 노드가 가득 차게 되면 중간값을 기준으로 리프 노드를 분리하고

 - 중간 값은 분리된 두 노드들의 dividing point를 나타내기 위해서 부모 노드로 승진한다(올라간다)

 

- 입력값

x : 가득 차지 않은 인터널 노드

i : x.c[i]가 x의 가득 찬 자녀인 i

 

- 출력값

없음

 x, y, z를 업데이트한다 

B-TREE-SPLIT-CHILD(x, i):
	y =x.c[i]

    // 새 노드 할당, 설정(leaf, n)
    z = ALLOCATE-NODE()
    z.leaf y.leaf
    z.n = t - 1
    
    // key : y의 t+1~2t-1부분을 z의 1~t-1 부분으로 붙여넣기 
    // c : y의 t+1~2t 부분을 z의 1~t부분으로 붙여넣기 
    for j = 1 to t - 1:
    	z. key[j] =y.key[j+t]
    if not y. leaf:
    	for j = 1 to t:
    		z.c[j] =y.c j + t
            
    // y의 n 줄이기
    y.n = t - 1
    
    // y의 t번째가 들어가기 위한 x의 i번째 자리 만들기
    for j=x.n + 1 downto i + 1:
    	x.c[j + 1] =x.c[j]
    x.c[i+1] = z
    
    for j =x.n downto i:
    	x.key[j+1]=x.key[j]
        
    // 키를 옮기고 x의 n을 바꾸기
    x. key[i] =y.key[t]
    x.n = x.n + 1

 

 

 

 

 

 

 

Case 1 : B트리의 루트가 가득 찬 경우

 - 새로운 노드 s를 만들고, 루트를 분할하여 s를 새로운 루트로 만든다

 - 키 k를 s를 루트로 하는 B트리에 삽입한다 

Case 2 : B트리의 루트가 가득 차지 않은 경우

 - 키 k를 루트가 가득 차지 않은 B트리에 삽입한다

 

BTreeInsert(T, k):
    r = T.root
    if r.n == 2t-1:
        s = ALLOCATE-NODE()
        T.root = s
        s.leaf = FALSE
        s.n = 0
        s.c[1] = r
        BTreeSplitChild(s, 1)
        BTreeInsertNonFull(s, k)
    else: 
        BTreeInsertNonFull(r, k)

 

 

 

루트를 분할하는 것이 B트리의 높이를 증가시키는 유일한 방법이다

 

BTreeInsertNonFull(x, k):
    if x.leaf:
        while i >= 1 and k < x.key[i]:
            x.key[i+1] = x.key[i]
            i = i-1
        x.key[i+1] = k
        x.n = x.n+1
    else:
        while i >= 1 and k < x.key[i]:
            i = i-1
        i = i+1
        // x.c[i]가 가득찬 경우
        if x.c[i].n == 2t-1:
            BTreeSplitChild(x,i)
            // x.c[i]가 두개로 분할 되었을 때 어느 쪽으로 내려가야 하는지 결정하는 부분
            if k > x.key[i]:
                i = i+1
        // 리프 노드가 발견 될 때까지 재귀적으로 반복될 것이다
        BTreeInsertNonFull(x.c[i], k)

 

 

시간 복잡도 : O(t*log t N)

 

 

삭제(Delete)

 

Case 1: 삭제될 키가 리프노드에 있는 경우 

 

   Case 1-(1) : 삭제될 키가 있는 노드의 x.n >= t인 경우

    - just delete the key

   Case 1-(2) : 삭제된 키가 있는 노드의 x.n == t-1 (minimum number of keys)인 경우

    - 노드의 키를 삭제하는 것은 B-tree 속성 위배로 이어지게 된다

    - Case 1-2-a : sibling 노드가 t개 이상의 키를 가지는 경우, sibling node로 부터 키를 빌려온다.

    - Case 1-2-b : sibliing 노드가 모두 키의 최소수를 가지는 경우, 부모 노드로 부터 키를 빌려와서 

                           sibling 노드와 병합한다. 이 과정을 거치면 부모 노드의 키가 1개 줄어드므로

                           이 과정 이후의 부모 노드의 키의 수를 확인해야 한다.

       * Case 1-2b로 키를 삭제한 이후 부모 노드의 키가 줄어드는데, 부모가 루트이고 자식 노드가 없다면

         B 트리의 높이가 줄어든다.

 

 

Case 2 : 삭제될 키가 인터널노드에 있는 경우

 

 - 이 케이스를 케이스 1으로 바꾼다

 - 삭제될 키가 속한 노드의 predecessor 혹은 successor을 찾는다

 - 삭제될 키를 predecessor로 대체한다

 - 이제 리프 노드에 있는 키를 삭제한다(case 1)

 

 

 

 

 

'Data Base' 카테고리의 다른 글
  • [DB] ER model
  • [DB] Basics
vysryoo
vysryoo
  • vysryoo
    vysryoo
    vysryoo
  • 전체
    오늘
    어제
    • 분류 전체보기 (129)
      • Python (20)
      • Data structure (12)
      • Algorithm (14)
      • Operating system (18)
      • Programming language theory (12)
      • Computer architecture (6)
      • Softeware engineering (8)
      • Multicore (2)
      • Data Base (3)
      • Problem solving (24)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
vysryoo
[DB] B-Tree
상단으로

티스토리툴바