key 탐색

// 4-1. 주어진 키 값에 해당하는 노드를 탐색하여 반환하는 함수
node_t *rbtree_find(const rbtree *t, const key_t key) {
  node_t *p = t->root; // 루트 노드부터 탐색 시작

  // 노드가 nil이 아닌 동안 반복
  while(p != t->nil) {
    // 현재 노드의 키 값과 찾고자 하는 키 값을 비교
    if(p->key == key)
      return p; // 키 값이 일치하는 경우 해당 노드를 반환
    else if(p->key > key) // 찾고자 하는 키 값이 현재 노드의 키 값보다 작은 경우
      p = p->left; // 현재 노드의 왼쪽 자식으로 이동
    else // 찾고자 하는 키 값이 현재 노드의 키 값보다 큰 경우
      p = p-> right; // 현재 노드의 오른쪽 자식으로 이동
  }

  return NULL; // 키 값을 가진 노드가 없는 경우
}

후계자 탐색

// 4-2. 주어진 노드의 다음 노드를 반환하는 함수 (후계자 찾기)
node_t *rbtree_successor(rbtree *t, node_t *x) {
    // 현재 노드의 왼쪽 자식이 nil이 아닌 동안 반복하여 탐색
    while(x->left != t->nil) {
      x = x->left; // 현재 노드의 왼쪽 자식으로 이동
    }
    return x; // 가장 왼쪽 자식 노드를 반환
}

최소값/최대값 탐색

// 4-3. 트리에서 최소값을 가진 노드를 탐색하여 반환하는 함수
node_t *rbtree_min(const rbtree *t) {
  node_t* x = t->root; // 루트 노드부터 시작

  // 현재 노드의 왼쪽 자식이 nil일때까지
  while(x->left != t->nil) {
    x = x->left; // 현재 노드의 왼쪽 자식으로 이동
  }
  return x; 
}

// 4-4. 트리에서 최대값을 가진 노드를 탐색하여 반환하는 함수
node_t *rbtree_max(const rbtree *t) {
  node_t* x = t->root; // 루트 노드부터 시작

  // 현재 노드의 오른쪽 자식이 nil일때까지
  while(x->right != t->nil) {
    x = x->right; // 현재 노드의 오른쪽 자식으로 이동
  }
  return x;
}