BTree的下溢+右旋转

时间:2018-10-25 18:04:17

标签: c++ tree b-tree

想知道你们是否可以为我提供简洁的解决方案来确定BTree是否下溢,以及是否可以对其进行正确的轮换。对于达到它的过程有些困惑。不要认为这就像比较两个无符号值一样容易(尤其是对于下溢)。

BTreeNode.h:

#ifndef BTREENODE_H
#define BTREENODE_H

#include <string>
#include <vector>

struct BTreeNode {
    bool is_leaf_ = true;
    std::vector<int> elements_;
    std::vector<BTreeNode*> children_;
    BTreeNode() {}
    BTreeNode(std::vector<int> v) {
      this->elements_ = v;
    }
/**
 * Fix the underflow child node at idx by rotating right 
 * (borrowing a node from left sibling).
 * @param idx The underflow child to be fixed is at children_[idx].
 * @return If the rotation can be done.
 */
    bool rotateRight(unsigned idx, unsigned order);
};

/**
 * Check if the given number of elements in a BTree node underflows.
 * @param numElem Number of elements in this node.
 * @param order The order of the BTree.
 * @return True if it underflows, False otherwise.
 */
     bool underflows(unsigned numElem, unsigned order);


/**
 * A special case for removing an element from BTree. Assume elem 
exists in leaf.
 * @param item The element to be removed.
 * @param parent The parent node that contains the leaf node as a 
child.
 * @param leaf_idx The leaf BTreeNode idx that contains the element to 
be removed.
 * @return If the removal is successful.
 */
    bool removeFromLeaf(int item, BTreeNode* parent, unsigned leaf_idx, 
    unsigned order);

#endif

BTreeNode.cpp:

#include "BTreeNode.h"
#include <assert.h>
#include <algorithm>
#include <iostream>

/**
 * Check if the given number of elements in a BTree node underflows.
 * @param numElem Number of elements in this node.
 * @param order The order of the BTree.
 * @return True if it underflows, False otherwise.
 */
bool underflows(unsigned numElem, unsigned order) {

    return false;
}

/**
 * Fix the underflow child node at idx by rotating right
 * (borrowing a node from left sibling).
 * @param idx The underflow child to be fixed is at children_[idx].
 * @return If the rotation can be done.
 */
bool BTreeNode::rotateRight(unsigned idx, unsigned order) {
    /**
     * First check if there is a left sibling.
     * If there is not, simply return false because rotateRight cannot 
be done.
     */
    if (idx <= 0)   return false;

    /**
     * Then check if the left sibling leaf contains enough elements 
after one being borrowed.
     */
   BTreeNode* prev = children_[idx - 1];
    if (underflows(prev->elements_.size() - 1, order)) {
        /**
         * If it's not enough, this case cannot be handled by 
rotateRight.
         * Simply return false.
        */
        return false;
    }
    /**
     * Do the right rotation by stealing one element from left sibling
     * and fixing the parent key.
     *
     * Example: Assume we are doing rotateRight around (40) to fix 
right child
     * (we are in BTreeNode(40), idx = 1 (the second child)),
     *                | 40 |
     *              /         \
     * | 10 | 20 | 30 |     | 60 |
     *
     * after rotation, the tree should look like
     *           | 30 |
     *         /        \
     * | 10 | 20 |    | 40 | 50 |
     *
     */

    // TODO: do the right rotation here

    return true;
 }

bool removeFromLeaf(int item, BTreeNode* parent, unsigned leaf_idx, 
   unsigned order) {
        // sanity checks
    assert(!parent->is_leaf_);
    assert(leaf_idx < parent->children_.size());
    BTreeNode* leaf = parent->children_[leaf_idx];
    assert(leaf->is_leaf_);
    std::vector<int>& elems = leaf->elements_;
    std::vector<int>::iterator pos = std::find(elems.begin(), 
elems.end(), item);
    assert(pos != elems.end());

    std::cout << "removing " << item  << "..." << std::endl;

    // delete item, shift other items, shrink the size
    elems.erase(pos);

     std::cout << "Does the node underflow? ";

    // call rotateRight if current leaf node underflows
    if (underflows(elems.size(), order)) {
        std::cout << "Yes!" << std::endl;
        return parent->rotateRight(leaf_idx, order);
    }
    std::cout << "No!" << std::endl;
    return true;
} 

0 个答案:

没有答案