Балансировка двоичного дерева поиска (BST)

Я пытаюсь сделать функцию баланса _bst (bstNode root ), но у меня проблемы с реализацией.

Я реализую функцию как функцию-шаблон, поскольку мой класс bstNode является классом-шаблоном.

Вот (некоторые из )моего кода:

template<class Item, class  Key>
class bstNode{
public:
    //Constructor
    bstNode(const Item& init_data = Item(), const Key& init_key = Key(), bstNode<Item, Key>* l_child = NULL, bstNode<Item, Key>* r_child = NULL){
        data_field = init_data;
        key_field = init_key;
        l_ptr = l_child;
        r_ptr = r_child;
    }
    //Destructor
    ~bstNode(){
        data_field = 0;
        key_field = 0;
        l_ptr = r_ptr = NULL;
    }
    //Basic Member Functions
    bstNode<Item, Key>*& left( )   {                    return l_ptr;       }           //returns left child pointer by reference
    bstNode<Item, Key>*& right( )  {                    return r_ptr;       }           //returns right child pointer by reference
    bstNode<Item, Key>* left( ) const   {               return l_ptr;       }       //returns left child pointer by reference
    bstNode<Item, Key>* right( ) const  {               return r_ptr;       }       //returns right child pointer by reference
    const Item& data() const{                           return data_field;  }           //returns reference to data_field
    const Key& key()const {                             return key_field;   }
    Item& data() {                                      return data_field;  }           //returns reference to data_field
    Key& key() {                                        return key_field;   }
    void set_data(const Item& new_data){            data_field = new_data;      }       //sets data_field to new_data
    void set_key(const Key& new_key){               key_field = new_key;        }       //sets key_field to new_key
    void set_left(bstNode* new_left){               l_ptr = new_left;           }       //sets left child pointer to new_left
    void set_right(bstNode* new_right){             r_ptr = new_right;          }       //sets right child pointer to new_right

private:
    bstNode<Item, Key>  *l_ptr,     //pointer to left child node 
                        *r_ptr;     //pointer to right child node
    Item    data_field;
    Key     key_field;
};

template<class Item, class Key>
void balance_bst(bstNode<Item, Key>*& root){                //unfinished

    std::vector< bstNode<Item, Key>* > nodes;
    sorter(root, nodes);
    size_t i = nodes.size()/2;                      //size() divided by 2 will yield
                                                    //index of middle element of vector for 
                                                    //odd-isized arrays and the greater of the 
                                                    //middle two elements for an even-sized array

    while(i>=0){
        root->set_key(nodes[i]->key());                             
        root->set_data(nodes[i]->data());
         //.....MORE CODE HERE: recursive call??

    }


}

template<class Item, class Key>
void sorter(bstNode<Item, Key>*& root, std::vector<bstNode<Item, Key>* >& tree_nodes){
    if(root == NULL)
        return;
    sorter(root->left(), tree_nodes);
    tree_nodes.push_back(root);
    sorter(root->right(), tree_nodes); 
}

Я возился с фактической функцией баланса _bst и думаю, что рекурсия является очевидным решением, но я не могу обернуть свой код подумайте об этом...

сортировщик в основном вставляет элементы BST в вектор, используя алгоритм обработки в неупорядоченном порядке. Таким образом, пока «root» является указателем на корень двоичного дерева поиска (, т. е. все ключевые значения узлов левого поддерева меньше, чем ключевое значение узлов, а все ключевые значения узлов правого поддерева больше чем узлы ), то узлы, вставленные в вектор, будут сортироваться по возрастанию.

Затем, чтобы создать сбалансированное дерево, я вставляю узел в центр вектора в корень дерева, а затем должен иметь возможность рекурсивно вставлять левый и правый дочерние узлы, которые затем будут в середине левая половина вектора и середина правой половины вектора.

Примечание :Я понимаю, что здесь используется целочисленное деление и, скажем, 7/2 = 3, что будет индексом среднего элемента массива размера 7. А для массивов четного размера -алгоритм, реализованный выше, найдет индекс большего из двух элементов в середине вектора.

В любом случае, любые предложения и замечания приветствуются и поощряются! Заранее спасибо.

Изменить :Я спрашиваю, как мне реализовать функцию для балансировки двоичного дерева поиска? (Сбалансированный BST — это тот, который имеет минимальную глубину, которую он может дать, учитывая количество узлов.)

6
задан ADJ 4 December 2018 в 07:59
поделиться