私はbalance_bst(bstNodeルート)関数を作成しようとしていますが、実装には苦労しています。分散バイナリ検索ツリー(BST)のバランスをとるにはどうすればよいですか?
私は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);
}
私は実際balance_bst機能をいじってきた、と再帰は明白な解決策だと思いますが、私は周りに私の頭をラップするように見えることはできませんこれは...
ソーターは基本的に、インオーダー処理アルゴリズムを使ってベクトルにBSTの要素を挿入します。したがって、「ルート」がバイナリ検索ツリーのルートへのポインタである限り(つまり、ノード左のサブツリーのすべてのキー値はノードのキー値より小さく、ノード右のサブツリーのすべてのキー値はノードに挿入されると、ベクトルに挿入されたノードは昇順に並べ替えられます。
次に、バランスの取れたツリーを作成するために、ツリーのルートにあるベクトルの中心にノードを挿入します。次に、中央にある左と右の子ノードを再帰的に挿入できます。ベクトルの左半分の中央とベクトルの右半分の中央に位置します。
注:これは整数除算を使用しており、7/2 = 3であることを理解しています。これはサイズ7の配列の中間要素のインデックスになります。また、上記のベクトルの中間にある2つの要素のうち大きい方のインデックスを見つけることができます。
とにかく、提案や観察は歓迎され、奨励されます!前もって感謝します。
編集:バイナリ検索ツリーのバランスをとる機能を実装するにはどうすればよいですか? (平衡型BSTは、ノードの数を指定できる最小の深さを持つものです)。
質問は何ですか? –
申し訳ありませんが、問題は:どのように私はバイナリ検索ツリーのバランスを取るのですか? – MRT89