이진 트리의 다양한 연산

이진 검색 트리를 활용한 다양한 연산 방법을 살펴봅니다. 아래 내용은 이진 검색 트리(BST)에서 값 검색, 유효성 확인, 최빈값 찾기, 공통 조상 찾기, 삽입 및 삭제 등을 다룹니다.

BST에서 값 검색

다음과 같이 반복문을 사용해 특정 값을 검색할 수 있습니다.


Node* searchBST(Node* root, int target) {
    if (!root) return nullptr;
    while (root) {
        if (root->data > target) root = root->left;
        else if (root->data < target) root = root->right;
        else return root;
    }
    return nullptr;
}

유효한 BST 확인

중위 순회를 통해 정렬된 상태를 확인하는 방식입니다.


bool isValidBST(Node* root) {
    Node* prev = nullptr;
    stack st;
    Node* curr = root;

    while (curr || !st.empty()) {
        while (curr) {
            st.push(curr);
            curr = curr->left;
        }

        curr = st.top();
        st.pop();

        if (prev && prev->data >= curr->data) return false;
        prev = curr;
        curr = curr->right;
    }
    return true;
}

BST에서 최빈값 찾기

DFS를 활용하여 각 노드의 빈도수를 계산합니다.


vector<int> findMode(Node* root) {
    unordered_map freqMap;
    function dfs = [&](Node* node) {
        if (!node) return;
        freqMap[node->data]++;
        dfs(node->left);
        dfs(node->right);
    };

    dfs(root);

    vector<int> result;
    int maxFreq = 0;
    for (const auto& pair : freqMap) {
        if (pair.second > maxFreq) {
            result.clear();
            result.push_back(pair.first);
            maxFreq = pair.second;
        } else if (pair.second == maxFreq) {
            result.push_back(pair.first);
        }
    }
    return result;
}

공통 조상 찾기

BST의 특성을 이용해 효율적으로 공통 조상을 찾습니다.


Node* lowestCommonAncestor(Node* root, Node* p, Node* q) {
    if (!root) return nullptr;
    if (p->data < root->data && q->data < root->data)
        return lowestCommonAncestor(root->left, p, q);
    if (p->data > root->data && q->data > root->data)
        return lowestCommonAncestor(root->right, p, q);
    return root;
}

BST에 노드 삽입하기

반복문을 활용한 삽입 방법입니다.


Node* insertIntoBST(Node* root, int value) {
    if (!root) return new Node(value);

    Node* curr = root;
    Node* parent = nullptr;

    while (curr) {
        parent = curr;
        if (value < curr->data) curr = curr->left;
        else curr = curr->right;
    }

    if (value < parent->data) parent->left = new Node(value);
    else parent->right = new Node(value);

    return root;
}

BST에서 노드 삭제하기

삭제 시 여러 가지 경우를 고려해야 합니다.


Node* deleteNode(Node* root, int key) {
    if (!root) return nullptr;

    if (key < root->data) root->left = deleteNode(root->left, key);
    else if (key > root->data) root->right = deleteNode(root->right, key);
    else {
        if (!root->left) return root->right;
        if (!root->right) return root->left;

        Node* minNode = root->right;
        while (minNode->left) minNode = minNode->left;

        root->data = minNode->data;
        root->right = deleteNode(root->right, minNode->data);
    }
    return root;
}

트리 자르기(Trim)

주어진 범위 외의 노드들을 제거합니다.


Node* trimBST(Node* root, int low, int high) {
    if (!root) return nullptr;

    if (root->data < low) return trimBST(root->right, low, high);
    if (root->data > high) return trimBST(root->left, low, high);

    root->left = trimBST(root->left, low, high);
    root->right = trimBST(root->right, low, high);
    return root;
}

정렬된 배열을 BST로 변환

중앙 값을 기준으로 재귀적으로 트리를 구성합니다.


Node* sortedArrayToBST(vector<int>& nums, int start, int end) {
    if (start > end) return nullptr;

    int mid = start + (end - start) / 2;
    Node* root = new Node(nums[mid]);
    root->left = sortedArrayToBST(nums, start, mid - 1);
    root->right = sortedArrayToBST(nums, mid + 1, end);
    return root;
}

Node* sortedArrayToBST(vector<int>& nums) {
    return sortedArrayToBST(nums, 0, nums.size() - 1);
}

누적 합 트리 만들기

오른쪽부터 탐색하며 누적 합을 적용합니다.


void convertToGreaterSumTree(Node* root, int& sum) {
    if (!root) return;

    convertToGreaterSumTree(root->right, sum);
    sum += root->data;
    root->data = sum;
    convertToGreaterSumTree(root->left, sum);
}

Node* bstToGst(Node* root) {
    int sum = 0;
    convertToGreaterSumTree(root, sum);
    return root;
}

태그: BST C++ 알고리즘

7월 24일 20:05에 게시됨