• Mindscape 🔥
    • Playlist 🎧
  • Algorithm

    • 1018번: 체스판 다시 칠하기
    • 1966번: 프린터 큐
    • Python 시간 초과 방지를 위한 팁
    • C++ std::vector 사용법 정리
    • Vim 사용 매뉴얼
  • Ubuntu

    • 리눅스 우분투 GRUB 폰트 변경
    • 우분투 이미지 비디오 썸네일(미리보기) 안 보임 문제 해결
    • Wine 환경에서 카카오톡 실행 시 explorer.exe 뜨지 않게 하는 법
    • 우분투 Wine 카카오톡 사진 이미지 스크린샷 붙여넣기
    • Wine 카카오톡 이모지 깨짐 문제 해결
    • Ubuntu 윈도우 애니메이션 끄기
  • Wellness

    • 차전자피 (Psyllium Husk)
    • 엑스트라 버진 올리브유 (Extra Virgin Olive Oil)
    • 자가비강세척 (Nasal Irrigation)
    • QCY HT08 (MeloBuds Pro Plus)
    • 콘서타 (Concerta)
    • 인데놀 (Inderal)
    • 설트랄린 (Sertraline)
    • 멜라토닌 (Melatonin)
    • 치경부 마모증
    • 바벨 스쿼트 (Barbell Squat)
  • Humanities

    • Nordvik, Russia
    • North Sentinel Island
    • 롱고롱고(Rongorongo)
    • 바로크 음악 (Baroque Music)
  • Design

    • 구글의 아이콘 대개편 — 6년 만의 실수 인정
    • 제럴드 젠타 — 럭셔리 스포츠 워치의 창시자
    • 바우하우스 — 현대 디자인의 원점
  • Brands

    • NOMOS Glashütte
    • Frédérique Constant
    • KZ (Knowledge Zenith)
    • 에스트라 (AESTURA)
    • JINHAO (金豪)
    • Herman Miller
    • 데스커 (DESKER)
    • 무신사 스탠다드 (Musinsa Standard)
  • Finance

    • 현대카드 ZERO — Edition2 vs Edition3 비교
    • 신한카드 처음
    • S&P 500 ETF 투자 가이드
    • 파킹통장 vs CMA 통장
    • 버크셔 해서웨이 (Berkshire Hathaway)
    • 비트코인(Bitcoin)
  • Products

    • 오디오 인터페이스 (Audio Interface)
    • 쿠루토가 (KURUTOGA)
    • CX31993 DAC 동글
    • 클렌징 밀크 (Cleansing Milk)
    • 피젯 토이 (Fidget Toy)
    • ThinkPad
  • Programming Languages

    • 8.0. Statement Level Control Structures
    • 8. Subprogram
    • 9. Implementing Subprogram
    • 10.1. Abstract Data Types and Encapsulation Constructs
    • 10.2. Support for Object Oriented Programming
    • 11. Concurrency
    • 12. FPL (1)
    • 13. FPL (2)
    • 14. Exception Handling and Event Handling
    • Final Exam

B+tree

작성 2026. 6. 12.·수정 2026. 6. 12.

B+tree Operation : Deletion

  • Function delete(value K, pointer P)
    • (K, P)(K,~P)(K, P)를 포함하는 leaf node LLL을 탐색
    • delete_entry(L, K, P) 호출
function delete(value K, pointer P)
    find the leaf node L that contains (K, P)
    delete_entry(L, K, P)
  • Function delete_entry(node N, value K, pointer P)
    • NNN에서 (K, P)(K,~P)(K, P) 제거
    • If (NNN이 root이고 NNN이 하나의 child만 가질 경우)
      • NNN의 child를 tree의 새 root로 설정하고 NNN을 삭제
    • Else if (NNN이 너무 적은 value/pointer를 가질 경우)
      • N′N'N′을 parent(N)의 이전 또는 다음 child로 설정
      • K′K'K′을 parent(N)에서 NNN과 N′N'N′ pointer 사이의 value로 설정
      • If (NNN과 N′N'N′의 entries가 단일 node에 맞을 수 있는 경우) /* Coalesce nodes */
        • ...
      • Else /* Redistribution: borrow an entry from N' */
        • ...
function delete_entry(node N, value K, pointer P)
    remove (K, P) from N
    if (N is the root and N has only one remaining child)
        then make the child of N the new root of the tree and delete N
    else if (N has too few values/pointers) then begin
        Let N' be the previous or next child of parent(N)
        Let K' be the value between pointers N and N' in parent(N)
  • NNN에서 entry (K, P)(K,~P)(K, P)를 제거
  • NNN이 entry 제거 후 underflow (너무 적은 수의 value/pointer) 상태인지 확인
  • Underflow 상태라면, parent(N)에서 NNN의 형제 node N' (이전 또는 다음)와 그 사이의 key K′K'K′를 찾음
        if (entries in N and N' can fit in a single node)
            then begin /* Coalesce nodes */
                if (N is a predecessor of N' ) then swap_variables(N, N')
                if (N is not a leaf)
                    then append K' and all pointers and values in N to N'
                else append all (K_i, P_i) pairs in N to N' ; set N'.P_n = N.P_n
                delete_entry(parent(N), K', N); delete node N
            end
  • delete_entry의 Coalesce nodes (병합) 과정
    • if (N is a predecessor of N') ...: 제일 왼쪽 node일 경우 오른쪽 형제 node와 swap
    • if (N is not a leaf) ...: 형제 node에 이정표가 되는 K′K'K′ 값을 삽입하고 자신의 key 개수만큼 형제 node에 key값과 pointer를 삽입. 옮겨진 pointer들이 참조하는 node들의 부모 node는 모두 형제 node를 가리켜야 함
    • else (N is a leaf) ...: 형제 node에 K′K'K′ 값 삽입 과정을 생략하고, 자신의 key 개수만큼 형제 node에 key값과 pointer를 삽입한 다음 마지막 pointer가 자신이 가리키던 형제 node를 가리키도록 함
        else begin /* Redistribution: borrow an entry from N' */
            if (N' is a predecessor of N) then begin
                if (N is a nonleaf node) then begin
                    let m be such that N'.P_m is the last pointer in N'
                    remove (N'.K_{m-1},~N'.P_m ) from N'
                    insert (N'.P_m,~K' ) as the first pointer and value in N,
                         by shifting other pointers and values right
                    replace K' in parent(N) by N'.K_{m-1}
                end
                else begin
                    let m be such that (N'.P_m,~N'.K_m ) is the last pointer/value pair in N'
                    remove (N'.P_m,~N'.K_m) from N'
                    insert (N'.P_m,~N'.K_m ) as the first pointer and value in N,
                         by shifting other pointers and values right
                    replace K' in parent(N) by N'.K_m
                end
            end
            else ... symmetric to the then case ...
        end
    end
  • delete_entry의 Redistribution (재분배) 과정
    • if (N' is a predecessor of N) 경우 (왼쪽 형제 node N'에서 빌려오는 경우)
      • if (N is a nonleaf node) ...: NNN node의 key값과 pointer 배열 값을 한 칸씩 뒤로 미룸. NNN의 pointer[0]이 왼쪽 형제 node에서 제일 오른쪽에 위치한 pointer가 가리키던 자식 node를 가리키도록 하고 부모 node 재설정. NNN의 가장 왼쪽에 위치한 key값은 K′K'K′ 값으로 새로운 이정표 역할. NNN의 부모 node 이정표 값은 형제 node에서 제일 오른쪽에 위치한 key값이 이정표 역할
      • else (N is a leaf node) ...: NNN node의 key값과 pointer 배열 값을 한 칸씩 뒤로 미룸. NNN의 왼쪽 형제 node에서 제일 오른쪽에 위치한 key값과 pointer 배열 값을 NNN의 제일 왼쪽 위치로 이동시키고 가리키는 부모 node 재설정

(질문) 만약 node가 이미 제일 왼쪽인 상태에서 Key Rotation을 해야하는 상황이라면?

  • N이 가장 왼쪽 node인 경우, "previous" (왼쪽) 형제 node가 없음

  • delete_entry logic의 Let N' be the previous or next child... 부분에 따라, N'은 "next" (오른쪽) 형제 node로 설정됨

  • 이 상황은 Redistribution (재분배) logic의 else ... symmetric to the then case ... 부분에 해당함

  • 즉, 왼쪽 형제 node (N')에서 마지막 entry를 가져오는 if (N' is a predecessor of N) case 대신, 오른쪽 형제 node (N')에서 첫 번째 entry를 가져오는 (symmetric) logic이 수행됨

  • Non-leaf node의 경우:

    • parent(N)의 K′K'K′ 값을 N의 마지막 key로 가져옴
    • N' (오른쪽 형제)의 첫 번째 pointer (N'.P_0)를 N의 마지막 pointer로 가져옴
    • N'의 첫 번째 key (N'.K_0)를 parent(N)의 K′K'K′ 자리로 이동시킴
    • N'에서 (N'.K_0, N'.P_0)를 제거
  • Leaf node의 경우:

    • N' (오른쪽 형제)의 첫 번째 entry (N'.K_0, N'.P_0)를 N의 마지막 entry로 가져옴
    • N'에서 (N'.K_0, N'.P_0)를 제거
    • parent(N)의 K′K'K′ 값을 N'의 새로운 첫 번째 key (기존 N'.K_1) 값으로 update함
최근 수정: 26. 6. 12. 오후 3:28
Contributors: kmbzn, Claude Sonnet 4.6

BUILT WITH

CloudflareNode.jsGitHubGitVue.jsJavaScriptVSCodenpm

All trademarks and logos are property of their respective owners.
© 2026 kmbzn · MIT License